简体   繁体   中英

Bind template to a model programmatically using angular JS

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM