0

Given an HTML template

<div class="info">
    <div class="title"><a href="property-detail.html">{{title}}</a></div>
    <div class="location">{{location}}</div>
    <div class="property-info clearfix">
        <div class="area"><i class="icon icon-normal-cursor-scale-up"></i>{{size}}<sup>2</sup></div>
        <div class="bedrooms"><i class="icon icon-normal-bed"></i>{{bedrooms}}</div>
        <div class="bathrooms"><i class="icon icon-normal-shower"></i>{{bathrooms}}</div>
    </div><div class="price">{{price}}</div>
    <div class="link">
        <a href="{{details}}">View more</a>
    </div>
</div>

And a model that fits this template (that is, has all the fields: title, location, price, etc.). I am looking for a way to programmatically bind the template to the model and then push the rendered results to an array. In pseudo-code I am looking to do something like that:

var boxes= [];
 for (var i = 0; i < items.length; i++) {
    var results = bind(template, items[i]);
    boxes.push(results);
}

Where items is an array of items which i got from the database or any other source, and bind is basically the function that is responsible to populate the template with the model.

It makes sense to use a directive. Not sure how to do that though.

Any idea if and how it can be done using Angular?

9
  • Do you want the bound template to end up in the DOM? Or do you just want it in the array for later use? Commented Sep 21, 2014 at 16:16
  • This looks like you are defining what a directive is for... Commented Sep 21, 2014 at 16:21
  • @bmceldowney I would like to use the array later on. Specifically, i would like to feed it to a map widget that i have and the widget requires an array of all the boxes (which are attached to points on the map) Commented Sep 21, 2014 at 16:24
  • @PSL yes it seems like something that can be done with a directive, but how do i take the results and push them to an array instead of adding them to the page by applying the directive name? Commented Sep 21, 2014 at 16:26
  • You will have an ng-repeat on the directive. ex:- <my-dir data-item="item" ng-repeat="item in boxes"></my-dir> and you would need to put boxes on the scope... If your template url needs to be dynamic based on some static situation then you can as well use templateUrl as a function that returns a templateName.. based on some attributes on the element Commented Sep 21, 2014 at 16:28

1 Answer 1

0

Normally you never want to manipulate DOM in anything other than a directive. But why be dogmatic about it? If you really need a compiled template in a string format (for 3rd party widget consumption or such like) then you can put together a service similar to the following:

angular.module('app', []);
angular.module('app').controller('MainCtrl', function ($scope, templateCompiler) {
  var boxes = [];
  var data = [{
      title: 'test',
      location: 'location!',
      size: 40,
      bedrooms: 'yes',
      bathrooms: 'uncertain',
      price: 'if you have to ask...',
      details: 'indeterminate'
  },{
      title: 'test2',
      location: 'somewhere',
      size: 'a woman never tells',
      bedrooms: 3.14,
      bathrooms: null,
      price: 1400,
      details: 'forthcoming'
  }];

  for (var i = 0; i < data.length; i++) {
    var results = templateCompiler.bind(data[i]);
    boxes.push(results);
  }
  
  $scope.boxes = boxes;
})

angular.module('app').service('templateCompiler', function ($compile, $templateCache, $rootScope) {
  var service = {}
  var template = $templateCache.get('boxTemplate');
  var scope;
  
  this.bind = function (data) {
    scope = $rootScope.$new();
    angular.extend(scope, data);
    var link = $compile(template);
    var content = link(scope);
    scope.$apply();
    return content.html();
  };  
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>

<div ng-app='app'>

  <script type="text/ng-template" id="boxTemplate">
    <div class="info">
        <div class="title"><a href="property-detail.html">{{title}}</a></div>
        <div class="location">{{location}}</div>
        <div class="property-info clearfix">
            <div class="area"><i class="icon icon-normal-cursor-scale-up"></i>{{size}}<sup>2</sup></div>
            <div class="bedrooms"><i class="icon icon-normal-bed"></i>{{bedrooms}}</div>
            <div class="bathrooms"><i class="icon icon-normal-shower"></i>{{bathrooms}}</div>
        </div><div class="price">{{price}}</div>
        <div class="link">
            <a href="{{details}}">View more</a>
    </div>
  </div></script>

  <!-- TO PROVE YOU GET THE DESIRED OUTPUT -->
  <div ng-controller="MainCtrl">{{boxes}}</div>
</div>

You also might consider wrapping your map widget in a directive.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.