Angular的值在打印时被解析,但不会作为指令属性
Angular value is parsed when printed, but not as a directive attribute
我有一个名为addressesForUser
的地址数组。我还有一个具有隔离作用域的"address"指令。
当我这样做时:
<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缺失,它会显示一个表单来输入一个新地址。后一部分工作得很好,但我不明白为什么它不读取entryid值。
编辑:当我不使用隔离范围(即我从指令中删除"范围:{}"),它的工作原理。但是我需要隔离作用域,所以我想我只需要一种方法来使属性包含在单个指令的作用域中。下面是一个稍微简化的地址指令代码:
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);
}
});
}
}
}]);
这里的问题实际上是,在指令中,你不能假设一个属性是准备好了,当link
函数运行。如果值是内插的,它通常是不可用的。访问属性的规范方式是通过$observe
:
link: function ( scope, element, attrs ) {
attrs.$observe( 'entryid', function ( val ) {
// do something with the val
});
}
如果您正在使用隔离作用域,那么为公共属性添加作用域属性可能是一个好主意,但是您仍然不应该假设该值在link
期间可用。如果值可能需要插值,您应该始终使用$observe
方法。
由于您的指令不修改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);
});
...
}
小提琴
经过一番修修补补,我偶然得到了解决方案。文档确实需要在这方面做更多的工作。
本质上,隔离作用域需要这样定义:scope: {entryid: "="}
,然后通过作用域访问该值,而不是像
那样通过attrs访问。console.log(scope.entryid);
- 与ng attr myCustomAttribute匹配的自定义属性指令
- 角度属性指令值
- 在angular中的指令中添加属性指令
- AngularJS - 包含嵌套属性指令的内容
- AngularJs 属性指令 2 路绑定
- 防损层,从角度元素指令传递属性指令
- AngularJS :使用角度属性指令将元素包装到自定义模板中
- 角度:在元素指令上添加属性指令
- 如何在 AngularJS 中使用属性本身将可写参数传递给属性指令
- 刷新 Angular 中自定义属性指令的元素
- 使用嵌入时,元素和属性指令之间是否有区别
- AngularJS - 有条件地使用属性指令
- 如何解析具有多个值的属性指令
- AngularJS中多属性指令的编译和链接顺序
- 可能的Angular属性指令错误
- 在ng-repeat中调用angularjs的属性指令
- 在ng-repeat中有条件地添加属性指令
- 如何在自定义属性指令中访问父范围
- 聚合物属性指令
- 将属性指令传递给元素指令