Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/446.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用angularjs呈现需要不同模板(具有不同变量)的混合json结果_Javascript_Json_Angularjs - Fatal编程技术网

Javascript 如何使用angularjs呈现需要不同模板(具有不同变量)的混合json结果

Javascript 如何使用angularjs呈现需要不同模板(具有不同变量)的混合json结果,javascript,json,angularjs,Javascript,Json,Angularjs,我想知道,当我有一个包含许多不同类型对象的响应时,最好的做法是什么: [ {"nodeClass":"Entity", "text":"foo","entityfield":"booz"}, {"nodeClass":"User","username":"bar","userfield":"baz"} ] 我对所有这些都有不同的模板: 对于实体: <div class="{{nodeClass}} capsule">{{entity.text}}:{{entity.entityfi

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

[
{"nodeClass":"Entity", "text":"foo","entityfield":"booz"},
{"nodeClass":"User","username":"bar","userfield":"baz"}
]
我对所有这些都有不同的模板:

对于实体:

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

<div class="{{nodeClass}} capsule">{{user.username}}:{{user.userfield}}</div>
{{user.username}:{{{user.userfield}
您将如何构造代码,以及使用哪些angularjs元素(ng repeat等)根据“nodeClass”的值(重新)使用正确的模板。请记住,我不想创建新的条件模板,除非它是唯一的解决方案

编辑:我已经找到了这些方法:但它们与我的要求大不相同。特别是最后一个最接近我想要的,但是我的模板通常有不同的变量名


谢谢

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

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

指令:

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 = '<div><h1>Entity Class Template</h1>{{data.text}}</div><hr/>';
          break;
        case 'User':
          template = '<div><h1>User Class Template</h1>{{data.username}}</div><hr/>';
          break;
      }
      $template = angular.element(template);
      $compile($template)(scope);
      el.append($template); 
    }  
  }
})
app.directive('templateSelector',函数($compile){
返回{
限制:“A”,
作用域:{},
链接:功能(范围、el、属性){
console.log(attr.tClass、attr.tVals)
var模板=“”;
scope.data=angular.fromJson(attr.tVals);
开关(属性tClass){
案例“实体”:
template='实体类模板{{data.text}}
'; 打破 案例“用户”: template='User Class template{{data.username}}
; 打破 } $template=angular.element(模板); $compile($template)(范围); el.追加($模板); } } })
HTML:


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

<div ng-repeat="data in dataset">
  <div
    class="capsule"
    ng-class="data.nodeClass"
    ng-bind="data.text"
    ng-if="data.nodeClass==='Entity'"></div>
  <div
    class="capsule"
    ng-class="data.nodeClass"
    ng-bind="data.username"
    ng-if="data.nodeClass==='User'"></div>
</div>


一种方法是使用动态生成的
ng include
url

HTML


您可以尝试通过
$http
在后台拉取
模板.html
,解析模板并替换与
ng repeat
变量名不匹配的变量名实例。然后将
html
template.html
发送到模板中包含
ng repeat
的指令(或控制器模板),通过
$('#elem').html(newHtml)插入新编辑的html
并对修改后的元素调用
$compile

你拉下来的模板可能是这样的

controller1/template1.html

<h1>{{item.data}} - {{item.name}}</h1>
<p>This is the view for controller 1.</p>

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

</div>
模板的获取、所需字符串的替换和模板的重新编译可以这样完成

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);
    });
}


下面是一个正在运行的示例

您对整体视图的预期结构是什么?还是会有多个视图?不清楚您的期望是什么,这将有助于确定最佳方案approach@MichailMichailidis不同的变量名是什么意思?模板有时使用
事物
实体
而不是
项目
?为什么不能使用与
ng repeat
在所有模板中使用的变量名相同的变量名?@michaillidis解析模板并进行字符串替换如何?然后从
getContentUrl(objType)
返回url以将其包含在转发器中。或者,您可以执行字符串替换并将模板插入DOM,然后在其上运行
$compile(domeElement)
。应该注意,整个问题都有相当多的注释…通常是一个迹象,表明从DOM中看不清楚start@MichailMichailidis我添加了一个有效的解决方案。这并不漂亮,还有很多工作要做,但这是一个概念的证明。不用担心过早的答案。但是这会呈现所有的值,并且不会对每个不同的节点类使用预定义的(不同的)模板—在我的真实案例中,大约是6。在这种情况下,这是数据集的结构吗?只是一个模板选择器和一个需要显示的值?它是一组值和一个属性,用于区分要使用的模板。如果该解决方案适合您,请参见。我已经在指令本身中包含了模板,但是如果您有更复杂的数据集和模板,您肯定会希望从指令中抽象出这些数据集和模板。您可以让switch函数设置templateUrl值,如本文所示:对象的其余值呢?另外,我认为ng bind只处理输入。我该如何使用外部模板文件?@MichailMichailidis
ng bind=“variable”
{{variable}}
@charlietfl在这一点上你是对的-我只是不知道,因为我不使用它们,因为它们比
{variable}
更详细,但我必须输入的内容除外。(投赞成票)好的,这与类似,但我的模板有不同的变量名。。也有解决方案吗?除非您使问题更加明确,否则您可以轻松地为模板路径和nodeClass@MichailMichailidis能否将模板名和数据对象定义作为所有不同对象中的标准属性名包含在json中?ie
{template:“xyz.html”,nodeClass:“className”…}
问题在于,与您的解决方案相反,我的模板没有通用的变量名,例如
-但有不同的名称-我多次更新了原始问题,我猜您在提交之前已经得到了更新。Thanks@sgwatstack我不明白为什么这会对我的问题有所帮助,尽管它缺少条件/映射逻辑-这会起作用-
app.controller('MainCtrl', function($scope) {
  $scope.data=[{"nodeClass":"Entity", "text":"foo"},{"nodeClass":"User","username":"bar"}];
  $scope.getContentUrl = function(nodeClass){
    return 'partials/'+nodeClass +'.html';
  }
});
<h1>{{item.data}} - {{item.name}}</h1>
<p>This is the view for controller 1.</p>

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

</div>
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);
    });
}