我有一个名为addressesForUser
的地址数组。我还有一个带有隔离范围的“地址”指令。
当我这样做时:
<div ng-repeat="add in addressesForUser" entryid="{{ add.id }}">{{ add.id }}</div>
一切都很好,对于三个地址,我得到以下生成的html:
<div entryid="1">1</div>
<div entryid="2">2</div>
<div entryid="3">3</div>
但是当我这样做时:
<address ng-repeat="add in addressesForUser" entryid="{{ add.id }}"></address>
然后在指令的链接函数中尝试console.log(attrs.entryid)
,我将“add.id”作为输出中的字符串。更糟糕的是,生成的html中的属性是未定义的 - 只有属性名称存在 - 所以它既不是1到3的数字,也不是字符串“add.id”。
我做错了什么?最终目标是在其entryid属性中读取每个地址指令,因此它可以独立自动填充并生成地址卡,或者如果缺少entryid,则会显示一个表单以输入新地址。后一部分工作正常,但我不明白为什么它没有读入入门值。
编辑:当我不使用隔离范围时(即我从指令中删除“scope:{}”),它可以工作。但我需要隔离范围,所以我想我只需要一种方法使属性包含在单个指令的范围内。这是一个略微剥离的地址指令代码:
myapp.directive('address', ['GeoService', '$http', function (gs, http) {
return {
restrict: 'E',
templateUrl: 'address.html',
scope: {
},
link: function (scope, element, attrs) {
scope.emptyForm = {
first_name: '',
last_name: '',
country: '',
city: '',
street: '',
phone: '',
is_def: '',
zip: '',
additional_info: '',
residence_type: ''
}
console.log(attrs.entryid);
scope.countries = gs.countries();
scope.resetAddressForm = function(e) {
scope.newAddressForm = scope.emptyForm;
}
scope.saveAddress = function() {
http.post('/users/saveaddress', scope.newAddressForm).then(function (response) {
console.log(response.data); // Do something
});
}
scope.$watch('newAddressForm.country', function(v) {
if (v != undefined) {
scope.cities = gs.cities(v);
}
});
}
}
}]);
答案 0 :(得分:2)
这里的问题实际上是在指令中不能假设在link
函数运行时属性已准备就绪。如果插值,则通常无法使用。访问属性的规范方式是$observe
:
link: function ( scope, element, attrs ) {
attrs.$observe( 'entryid', function ( val ) {
// do something with the val
});
}
如果您正在使用隔离范围,那么为公共属性添加范围属性可能是个好主意,但您仍然不应假设在link
期间可以使用该值。如果可能需要插值,则应始终使用$observe
方法。
答案 1 :(得分:1)
由于您的指令不修改add.id
的值(因此您不需要双向数据绑定),我建议使用@
而不是=
。使用@
定义后,您可以使用attrs.$observe()
或scope.$watch()
来获取插值:
scope: {
entryid: '@',
},
link: function (scope, element, attrs) {
attrs.$observe('entryid', function(value) {
console.log('observed value=',value);
});
scope.$watch('entryid', function(value) {
console.log('watched value=',value);
});
...
}
答案 2 :(得分:0)
经过一些修补,我偶然得到了解决方案。该文档可以在这方面真正使用更多的工作。
基本上,隔离范围需要定义如下:
scope: {entryid: "="}
然后通过范围访问该值,而不是通过attrs访问,如
console.log(scope.entryid);