关于javascript:如何使用angularJS呈现不同模板(具有不同变量)所需的混合JSON结果

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

我想知道,当我有一个包含许多不同类型对象的响应时,最佳实践是什么:

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

我对所有这些都有不同的模板:

实体:

1
{{entity.text}}:{{entity.entityfield}}

用户:

1
{{user.username}}:{{user.userfield}}

您将如何构造代码,以及使用哪种AngularJS元素(ng repeat等)根据"nodeClass"的值重新使用正确的模板。请记住,我不想创建新的条件模板,除非它是唯一的解决方案。

编辑:我发现了以下方法:http://onehungrymind.com/angularjs-dynamic-templates/和angularjs模板中的if else语句以及angularjs中的ng repeat指令中的动态显示模板?但它们与我的要求大不相同。尤其是最后一个模板最接近我想要的,但是我的模板中通常有不同的变量名。

谢谢


一种方法是使用动态生成的ng-includeURL

HTML

1
 

模板

1
2
3
4
5
  <script type="text/ng-template" id="partials/Entity.html">
    Entity Template , text= {{item.text}}
 
  <script type="text/ng-template" id="partials/User.html">
    User Template , username ={{item.username}}

JS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
app.controller('MainCtrl', function($scope) {
  $scope.data=[{"nodeClass":"Entity","text":"foo
<div class="
suo-content">[collapse title=""]<ul><li>(向上投票)好的,这类似于stackoverflow.com/questions/16155542/&hellip;,但是我的模板有不同的变量名。还有解决办法吗?</li><li>直到你的问题更加明确,才可以很容易地为模板路径和nodeclass创建一个哈希图。</li><li>@michailmichailidis可以将模板名和JSON中的数据对象定义作为标准属性名包含在所有不同的对象中吗?即<wyn>{ template:"xyz.html", nodeClass:"className" ... }</wyn>。</li><li>问题是,与您的解决方案和stackoverflow.com/questions/16155542/&hellip相反,我的模板没有通用的变量名,例如<wyn>item</wyn>,但有不同的名称,我多次更新了原始问题,我猜您在提交之前已经获得了更新。谢谢</li><li>@斯格沃特斯塔克,我不明白为什么这会帮助我解决问题。</li><li>@是的,我甚至可以在getContentURL()中使用switch case语句。但这仍然不能解决上述两条评论的问题。</li></ul>[/collapse]</div><hr>
<p>
You can try pulling the <wyn>template.html</wyn> in the background via <wyn>$http</wyn>, parse the template and replace instances of the variable name that doesn't match your <wyn>ng-repeat</wyn> variable name. Then send that <wyn>html</wyn> from the <wyn>template.html</wyn> to a directive (or controller template) that has the <wyn>ng-repeat</wyn> in its template, insert the newly edited html via <wyn>$('#elem').html(newHtml);</wyn> and call <wyn>$compile</wyn> on the modified element.
</p>

<p>
The template you pull down could look like this
</p>

<p>
<wyn>controller1/template1.html</wyn>
</p>

[cc lang="
javascript"]{{item.data}} - {{item.name}}

这是中继器所在的模板

controller1.html

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

获取模板、替换所需字符串和重新编译模板可以这样做

controller1.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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);
    });
}

这是一个行动中的工作


我可能在服务到达视图之前修改它的数据。这通过使用ng if来确定要显示的HTML来实现:

1
2
3
4
5
6
7
8
9
10
  <div
    class="capsule"
    ng-class="data.nodeClass"
    ng-bind="data.text"
    ng-if="data.nodeClass==='Entity'">
  <div
    class="capsule"
    ng-class="data.nodeClass"
    ng-bind="data.username"
    ng-if="data.nodeClass==='User'">

从TPIe中拨出的拨叉


我构建了一个指令,它有两个属性——一个用于模板,另一个用于需要传递到模板中的任何数据。

通过switch语句传递模板选择器值,然后该语句将应用正确的模板并对数据进行适当的排序。柱塞

指令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
app.directive('templateSelector', function($compile) {
  return {
    restrict: 'A',
    scope: {},
    link: function(scope, el, attr) {
      console.log(attr.tClass, attr.tVals)
      var template ='';
      scope.data = angular.fromJson(attr.tVals);
      switch (attr.tClass) {
        case 'Entity':
          template = 'Entity Class Template{{data.text}}<hr/>';
          break;
        case 'User':
          template = 'User Class Template{{data.username}}<hr/>';
          break;
      }
      $template = angular.element(template);
      $compile($template)(scope);
      el.append($template);
    }  
  }
})

HTML:

1