我有一个指令pr-items
使用模板和pr-item
渲染子指令ng-repeat
的实例:
app.directive('prItems', function(){
console.log('prItems');
return {
restrict: 'E',
scope: {
items:'=',
},
template:'<pr-item ng-repeat="item in items"></pr-item>',
...
});
子指令pr-item
使用另一个模板呈现内容:
app.directive('prItem', function($compile){
console.log('prItem');
return {
restrict: 'E',
template: '<div ng-style="{\'border-style\':item.border_style, \'color\':item.color}" style="cursor:pointer;"><span ng-if="item.selected">* </span>{{item.name}} {{item.selected}}</div>',
...
});
到目前为止一切正常。
单击该项目后,将通过$emit
使用事件通知父指令。当父元素更改其中一个项目的状态时,此更改不会显示在相应项目中,如此Plunk中所示。
现在我很好奇我失踪了。
答案 0 :(得分:1)
我试图记录我的更改(与您的版本相反)
app.directive('prItems', function(){
console.log('prItems');
return {
restrict: 'E',
scope: {
items:'=',
},
template:'<pr-item ng-repeat="item in items"></pr-item>',
link: function (scope, elem, attr) {
console.log('prItems.link, scope.$id = ' + scope.$id);
scope.$on('onSelecting', function (event, item) {
console.log('prItems: onSelecting ' + item.name);
//clear the selected flag for the other items
angular.forEach(scope.items, function (value) {
if (value.selected) {
//console.log(value);
value.selected = false;
}
});
//set it for the item that was sent in
item.selected = true;
//change, no $scope.$apply - not needed here
});
}
};
});
app.directive('prItem', function($compile){
console.log('prItem');
return {
restrict: 'E',
//ng-style will change camel case to - case borderStyle works (instead of using 'border-style' with escaped quotes.
template: '<div ng-style="{borderStyle:item.border_style, \'color\':item.color}" style="cursor:pointer;">CLICK ME: <span ng-if="item.selected">* </span>{{item.name}} {{item.selected}}</div>',
controller: function ($scope, $element) {
console.log('prItem.controller, $scope.$id = ' + $scope.$id);
//I left this in as-is, but there is a better way to do this by just using the template ($watch shouldn't be required)
$scope.$watch('item.selected', function (val) {
console.log('prItem.selected ' + $scope.item.name + ' changed to ' + val);
$scope.item.border_style = val ? 'solid' : 'none';
//console.log('$scope.item.border_style = ' + $scope.item.border_style);
});
},
link: function (scope, elem, attr) {
console.log('prItem.link ' + scope.item.name + ', scope.$id = ' + scope.$id);
elem.on('mousedown touchdown', function () {
//console.log('touché!');
//scope.$apply should "wrap" non-angular code. In the old version , you were calling scope.$apply() inline
scope.$apply(function(){
scope.$emit('onSelecting', scope.item);
//instead of changing scope.selected, change item.selected - this change was probably not necessary
item.selected = !item.selected;
});
//old $scope.$apply();
});
}
};
});
编辑:没有$ watch
app.directive('prItem', function($compile){
console.log('prItem');
return {
restrict: 'E',
//ng-style will change camel case to - case borderStyle works (instead of using 'border-style' with escaped quotes.
template: '<div ng-style="{borderStyle:item.selected ? \'solid\' : \'none\', \'color\':item.color}" style="cursor:pointer;">CLICK ME: <span ng-if="item.selected">* </span>{{item.name}} {{item.selected}}</div>',
controller: function ($scope, $element) {
console.log('prItem.controller, $scope.$id = ' + $scope.$id);
},
link: function (scope, elem, attr) {
console.log('prItem.link ' + scope.item.name + ', scope.$id = ' + scope.$id);
elem.on('mousedown touchdown', function () {
//console.log('touché!');
//scope.$apply should "wrap" non-angular code. In the old version , you were calling scope.$apply() inline
scope.$apply(function(){
scope.$emit('onSelecting', scope.item);
//instead of changing scope.selected, change item.selected - this change was probably not necessary
item.selected = !item.selected;
});
//old $scope.$apply();
});
}
};
});