编辑:分叉@EliteOctagon的plunker奇怪它正在工作!无法理解为什么下面的代码不是。 http://plnkr.co/edit/y8uvulA9RHQ1Y9mwzin1
EDIT2:分叉前一个plunker并为控制器的逻辑添加$ timeout,它停止工作!猜猜它真的是在加载订单。请查看:http://plnkr.co/edit/ivmGQmEHTatNzBWhppyf
我是棱角分明的新手,无法将我的脑袋缠绕在指令隔离范围内。
我需要创建一个指令,在我的页面中打印出<span/>
,其中包含视图控制器中的信息和对象。
我试图做的是隔离指令范围并通过具有双向绑定的属性传递对象(请参阅下面的代码)。但是,当尝试访问指令的link
函数中的对象时,它总是以未定义的形式出现。
我在这里缺少什么?
先谢谢你们。
在html视图模板中使用指令:
<party-starts party="party"></party-starts>
指令JS代码
.directive('partyStarts', function(){
return {
restrict: 'E',
template: '<div id="partyStart><i class="icon ion-pin"></i> </div>',
scope: {
party: '='
},
link: function(scope, el) {
var party = scope.party;
var icon = el.find('i');
var statusStr = angular.element('<span/>');
var final;
console.log('scope '+scope);
if(party.Diatodo){
if(party.datahora.isSame(moment(), 'day') || party.datahora.isSame(moment().add(1, 'd'), 'day')){
icon.css({
'color': 'green'
});
statusStr.text(' É hoje');
el.append(statusStr);
}else{
icon.css({
'color': '#999'
});
statusStr.text(' Começa em '+party.datahora.fromNow());
el.append(statusStr);
}
return;
}
if(party.datahora.unix() == party.datahoraf.unix()){
final = party.datahora.clone().add(1, 'd').hour(6);
}else{
final = party.datahoraf;
}
if(party.datahora.twix(final).isCurrent()){
icon.css({
'color': 'green'
});
statusStr.text(' Começou há '+party.datahora.fromNow());
el.append(statusStr);
}else if(party.datahora.twix(final).isFuture()){
icon.css({
'color': '#999'
});
statusStr.text(' Começa em '+party.datahora.fromNow());
el.append(statusStr);
}else{
icon.css({
'color': 'red'
});
statusStr.text(' Já terminou');
el.append(statusStr);
}
}
};
})
答案 0 :(得分:9)
我不认为这是加载顺序的问题。据我所知,您提供的代码应该起作用。这是一个带有工作示例的plunker:
http://plnkr.co/edit/Bsn3Vyjrmb311b8ykzU1还有一个登录控制台,它会验证scope.party
是否在加载时使用正确的值进行初始化。
点击实时预览(右侧边栏上的眼睛图标)查看示例。
此外,这是一个图表,在我的推文提要中显示,我发现这对于以可理解的方式解释隔离范围非常有用。希望这会有所帮助: - )
答案 1 :(得分:8)
将指令的派对范围变量包装在观察程序中并等待它被初始化。在你的情况下,你没有这样做,所以你的所有逻辑都在分配scope.party之前运行。
link: function(scope, el) {
var watcher = scope.$watch('party', function() {
if(scope.party === undefined) return;
// at this point it is defined, do work
// delete watcher if appropriate
watcher();
})
}
答案 2 :(得分:0)
就我而言,之所以未定义是因为时机不正确。假设您有一个显示产品列表的指令:
<my-products products='httpLoadedProducts'>/<my-products>
你定义它是这样的:
.directive('myProducts', function () {
return {
restrict: 'E',
scope: {
products: '=',
},
templateUrl: 'directives/products-template.html',
link: function (scope, element, attrs) {
console.log(scope.products);
}
}
})
如果产品列表来自HTTP请求,则很可能在产品加载之前指令,因此console.log
打印undefined
一种解决方案是在项加载后实例化指令。这将确保在加载项目后运行link
函数。
所以,用ng-if
包装指令,如下所示:
<div ng-if='httpLoadedProducts'>
<my-products products='httpLoadedProducts'>/<my-products>
</div>
或者使用wbeange的答案来观察模型的变化。