我有以下角度代码:
<tr ng-repeat="vm in ...">
<span ng-if="myLookupFunc(vm)"> {{myLookupFunc(vm)).label}}, {{myLookupFunc(vm).uuid}}
<span ng-if="!myLookupFunc(vm)">-</span>
</tr>
正如您所看到的,对于单个项目,myLookupFunc被调用4次。 如何对其进行优化,以便只为给定的“vm”实例调用一次? 我确实尝试在'tr'级别使用ng-init,但是在'vm'的属性发生变化之后它没有重新评估 - 并且它是预期的,根据文档ng-init不应该用于这种情况。
那么angularjs实现这个目标的正确方法是什么?
答案 0 :(得分:0)
请检查以下代码以获得更好的优化。
<tr ng-repeat="vm in ..." ng-init="lookupData=myLookupFunc(vm)">
<span ng-if="lookupData"> {{lookupData.label}}, {{lookupData.uuid}}
<span ng-if="!lookupData">-</span>
</tr>
答案 1 :(得分:0)
ng-init
将在ng-repeat
开始时运行一次。这就是为什么它不会为你改变。
您必须使用控制器来获取变量数据,但可以改进它。
一种方法是在您的控制器上执行此操作:
function lookup(vm, firstRun) {
if (firstRun) {
$scope.lookupVar = myLookupFunc(vm);
}
else {
return $scope.lookupVar;
}
}
然后你可以保持你的HTML代码几乎相同:
<tr ng-repeat="vm in ...">
<span ng-if="lookup(vm, true)"> {{lookup(vm)).label}}, {{lookup(vm).uuid}}
<span ng-if="!lookup(vm)">-</span>
</tr>
更好的解决方案只是在HTML中保留一个范围然后执行:
<tr ng-repeat="vm in ...">
<span>{{getVmText(vm)}}</span>
</tr>
在控制器上定义一个函数getVmText
,用于检查VM值并返回文本。我相信这是更好的方式。
答案 2 :(得分:0)
使用数据模型并在必要时进行更新(即使发生&#34;外部事件&#34;)。通过这种方式,您不必费心去重新评估控制器功能&#34;它只是纯粹的角度数据绑定。
示例:
$scope.vms = ["id1", "id2", "id3"];
// this var will hold your data model (it could also be on the $scope, but for
// demo let's leave it like this)
var data = {
"id1": {
uuid: "123-123",
label: "label 1"
},
"id2": {
uuid: "456-456",
label: "label 2"
},
"id3": {
uuid: "abc-abc",
label: "label 3"
}
};
$scope.myLookupFunc = function(id) {
return data[id];
};
然后你可以像这样使用它:
<div ng-repeat="vm in vms" ng-init="lookupData=myLookupFunc(vm)">
<span ng-if="lookupData"> {{lookupData.label}}, {{lookupData.uuid}}</span>
<span ng-if="!lookupData">-</span>
</div>
答案 3 :(得分:0)
好的,在考虑了上述建议之后,我发现了我认为最简单的解决方案。
我们只需要运行
{{lookupData = myLookupFunc(vm)}}
之后我们可以引用'lookupData'变量。如果我们只是内联运行上面的代码,它也会评估并显示内联的结果(作为JSON字符串化文本),这不是我们想要的。所以我最终创建了一个专用指令,这是一个noop指令:
app.directive("ngAssign", function () {
return {
restrict: 'A'
};
});
然后可以说:
<tr ng-repeat="vm in ..." ng-assign={{lookupData = myLookupFunc(vm)}}>
<span ng-if="lookupData"> {{lookupData.label}}, {{lookupData.uuid}}
<span ng-if="!lookupData">-</span>
</tr>
Full plunker:http://plnkr.co/edit/34DwCGR7Po8zg2mnCAtB?p=preview