Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render mixed json results in need for different templates (with distinct variables) using angularjs

I wonder what is the best practice when I have a response that has many different types of objects and looks like that:

[
{"nodeClass":"Entity", "text":"foo","entityfield":"booz"},
{"nodeClass":"User","username":"bar","userfield":"baz"}
]

and I have different templates for all of those:

for Entities:

<div class="{{nodeClass}} capsule">{{entity.text}}:{{entity.entityfield}}</div>

for Users:

<div class="{{nodeClass}} capsule">{{user.username}}:{{user.userfield}}</div>

how would you structure the code and with which angularjs elements (ng-repeat etc) to (re)use the correct templates based on the value of "nodeClass". Keep in mind that I don't want to make a new conditional template except if it is the only solution.

Edit: I have found those approaches: http://onehungrymind.com/angularjs-dynamic-templates/ and if else statement in AngularJS templates and Dynamically displaying template in ng-repeat directive in AngularJS? but they are quite different than my requirements. Especially the last one is the closest to what I want but my templates as usually have different variable names in them..

Thanks

like image 944
Michail Michailidis Avatar asked Jan 17 '26 02:01

Michail Michailidis


2 Answers

One way is to use a dynamically generated ng-include url

HTML

  <div ng-repeat="item in data">
    <div ng-include="getContentUrl(item.nodeClass)"></div>
  </div>

Templates

  <script type="text/ng-template" id="partials/Entity.html">
    <h3>Entity Template , text= {{item.text}}</h3>
  </script>
  <script type="text/ng-template" id="partials/User.html">
    <h3>User Template , username ={{item.username}}</h3>
  </script>

JS

app.controller('MainCtrl', function($scope) {
  $scope.data=[{"nodeClass":"Entity", "text":"foo"},{"nodeClass":"User","username":"bar"}];
  $scope.getContentUrl = function(nodeClass){
    return 'partials/'+nodeClass +'.html';
  }
});

DEMO

like image 86
charlietfl Avatar answered Jan 19 '26 15:01

charlietfl


You can try pulling the template.html in the background via $http, parse the template and replace instances of the variable name that doesn't match your ng-repeat variable name. Then send that html from the template.html to a directive (or controller template) that has the ng-repeat in its template, insert the newly edited html via $('#elem').html(newHtml); and call $compile on the modified element.

The template you pull down could look like this

controller1/template1.html

<h1>{{item.data}} - {{item.name}}</h1>

Here is the template that the repeater sits in

controller1.html

<p>This is the view for controller 1.</p>

<div id="repeater" ng-repeat="thing in vm.items">

</div>

The fetching of the template, replacing of the desired string and re-compiling of the template can be done like this

controller1.js

function Controller1($scope, $http) {
    var vm = this;

    vm.items = [{name: 'item1', data: 123}, {name: 'item2', data: 456}];

    var templateReplacement = '{{thing.';
    $http.get('controller1/template1.html')
        .then(function success(response) {
            var newHtml = response.data.replace(/{{item./g, templateReplacement);
            var repeaterElem = $('#repeater');

            $(repeaterElem[0]).html(newHtml);

            $compile(repeaterElem)($scope);
    }, function failure(reason) {
            console.log(reason);
    });
}

Here is a plunk of this working in action

like image 34
seangwright Avatar answered Jan 19 '26 16:01

seangwright



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!