我刚刚碰到过这个,我想知道它是不是一个错误或预期的行为?这只是一个显示问题的小例子。以下代码用于两个示例:
<body ng-app="app" ng-controller="AppCtrl">
<item-directive ng-repeat="item in ::items" item="item"></item-directive>
</body>
angular
.module('app', [])
.controller('AppCtrl', AppCtrl)
.directive('itemDirective', itemDirective)
.factory('model', model);
function AppCtrl($scope, model) {
$scope.items = model.getItems();
}
function itemDirective() {
return {
restrict: 'E',
replace: true,
scope: {
item: '='
},
templateUrl: 'item-directive.html'
};
}
function model() {
return {
getItems: getItems
}
function getItems() {
return [
{
type: 'test',
title: 'test 1'
},
{
type: 'test',
title: 'test 2'
},
{
type: 'test',
title: 'test 3'
}
];
}
}
第一个示例有这个item-directive.html,它按照预期的正确顺序呈现
<div>
<span>{{::item.title}}</span>
</div>
但是第二个例子 - 它有以下item-directive.html - 包含一个ng-if
,导致列表以相反的顺序呈现?
<div ng-if="item.type == 'test'">
<span>{{::item.title}}</span>
</div>
--------更新----------
我刚刚注意到(这与@squiroid的回答中提到的问题有关),隔离范围在这个例子中实际上并不起作用。它似乎是,但是item
范围内item-directive
范围(或者更确切地说是范围)可以使ng-repeat
可用,而不是隔离范围。如果您尝试在隔离范围上设置任何其他值,即使它们显示在传递给指令的链接和控制器功能的范围内(可以在plnkr的控制台输出中看到),它们&#39 ;不可用于模板。除非您删除replace
。
Plunkr showing broken isolate scope
Plunkr showing fixed isolate scope when replace:false
---更新2 ---
我已更新了两个示例,以便在删除隔离范围后显示问题仍然存在
Plunkr without ng-if and no isolate scope
Plunkr with ng-if and no isolate scope
还有一个新版本显示了从templateUrl到模板的更改 - 正如@Manube所建议的那样 - 显示了按预期工作的行为
Plunkr with ng-if and no isolate scope using template instead of templateUrl
答案 0 :(得分:1)
它与templateUrl有关,它是异步的;
如果您用
替换templateUrl template:'<div ng-if="item.type === \'test\'"><span>{{::item.title}}</span></div>'
它将按预期工作:see plunker with template instead of templateUrl
当范围准备好并且已获取templateUrl时,将执行测试<div ng-if="item.type === 'test'">
。
由于获取模板的方式是异步的,无论哪个模板首先执行测试,都会显示该项目。
现在的问题是:为什么它总是最后一个模板?
答案 1 :(得分:1)
组合使用replace:'true'和ng-if在根元素上。
确保templateUrl中html的内容只有一个根元素。
如果你把ng-if放在span
上<div >
<span ng-if="item.type == 'test'">{{::item.title}}</span>
</div>
现在为什么会发生这种情况,因为ngIf指令基于{expression}删除或重新创建DOM树的一部分。如果分配给ngIf的表达式求值为false值,则从DOM中删除该元素,否则将元素的克隆重新插入DOM中。
在渲染时可能导致templateUrl上没有根元素,从而导致不必要的行为。
答案 2 :(得分:0)
第二个以相反的顺序显示由于使用item-directive name定义的自定义指令,但由于使用了replace = true而没有呈现为DOM。
如需更多参考,请参阅this link