我有一个大数据结构,我想使用Angular指令显示。
{
name: 'structure',
groups: [{
name: 'one group',
entries: [{
name: 'a',
type: 'a'
}, {
name: 'b',
type: 'a'
}]
}, {
name: 'other group',
entries: [{
name: 'c',
type: 'b'
}, {
name: 'd',
type: 'a'
}]
}]
}
目前,我的指令将整个对象包含为值:
<!-- main.html -->
<div ng-repeat="group in groups">
<my-group group-data="{{group}}"></my-group>
</div>
<!-- group.html -->
<div ng-repeat="entry in group.entries>
<my-entry entry-data="{{entry}}"></my-entry>
</div>
<!-- entry.html -->
<div ng-if="entry.type === 'a'>{{entry.name}}</div>
// directives.js
angular.module('my-module')
.directive('my-group', function() {
return {
templateUrl:'group.html',
link: function (scope, element, attributes) {
scope.$watch(attributes.groupData, function(value) {
scope.group = value;
});
}
});
// similar for my-entry
只要结构不变,这就有效。问题是,当范围中groups
的某些条目的值发生变化时,更改会在main.html
中传播并显示,但不会在group.html
或entry.html
中传播。此外,整个对象都包含在DOM中,感觉不对。
我尝试在我的指令上使用scope: {group: '='}
,但后来我根本没有得到价值。我已经尝试使用attributes.$observe('group', function (value) { /* same impl */ })
而不是scope.$watch
,但这似乎将对象作为字符串接收,因此我无法在不解析它的情况下访问单个属性(这感觉更加错误)。
如何将对象树传递给指令,并观察它的变化?
答案 0 :(得分:1)
您正在使用$ watch错误。 $ watch的参数必须是范围内变量的名称,或者是返回某个值的函数。此外,没有必要手动观察这个参数更好地使用指令范围:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
</head>
<body ng-app="my-module" data-ng-controller="myController">
<div ng-repeat="group in groups">
<my-group group-data="group"></my-group>
</div>
<button type="button" ng-click="changeEntryName()">Change</button>
<script>
var app = angular.module('my-module', [])
.controller('myController', ['$scope', function($scope) {
$scope.groups = [{
name: 'one group',
entries: [{
name: 'a',
type: 'a'
}, {
name: 'b',
type: 'a'
}]
}, {
name: 'other group',
entries: [{
name: 'c',
type: 'b'
}, {
name: 'd',
type: 'a'
}]
}];
$scope.changeEntryName = function() {
$scope.groups[0].entries[0].name = 'Kowabunga!';
};
}])
.directive('myGroup', function() {
return {
templateUrl:'group.html',
scope: {
group: '=groupData'
}
}
})
.directive('myEntry', function() {
return {
templateUrl:'entry.html',
scope: {
entry: '=entryData'
}
}
});
</script>
<script type="text/ng-template" id="group.html">
<div ng-repeat="entry in group.entries">
<my-entry entry-data="entry"></my-entry>
</div>
</script>
<script type="text/ng-template" id="entry.html">
<div ng-if="entry.type === 'a'">{{entry.name}}</div>
</script>
</body>
</html>