请考虑以下代码:它具有带隔离范围的指令myItem
。每个项目都会显示一个按钮,该按钮将在指令控制器上调用delete()
。我希望在外部控制器中触发refresh
(AppController
)。但是,由于孤立的范围,当然无法找到refresh()
函数。
<html>
<body ng-app="question">
<div ng-cloak ng-controller="AppController">
<my-item ng-repeat="item in list" data="list">
</my-item>
<input type="text" maxlength="50" ng-model="new_item" />
<button ng-click="add(new_item)">+</button>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script>
(function () {
var app;
app = angular.module('question', []);
app.controller('AppController', [
'$scope', '$http', function ($scope, $http) {
$scope.list = [];
function refresh(){
$http.get('/api/items').then(
function(response){
$scope.list = response.data;
}
);
}
$scope.add = function(item){
$http.post('/api/items', { item: item }).then(refresh);
};
refresh();
}
]);
app.directive('myItem', function() {
return {
scope: {
item: '=data',
},
// directive template with delete button
template: '{{ item }} <button ng-click="delete(item)">-</button>',
restrict: 'E',
// directive controller with delete function
controller: [ '$scope', '$http', function($scope, $http) {
$scope.delete = function (card) {
// This is where it goes wrong! refresh does not exist
$http.delete('/api/items' + card.id).then(refresh);
}
}]
};
});
})();
</script>
</body>
</html>
我可以做的一件事是在myItem指令中添加ng-change,但这需要使用ngModelController,这看起来有点过分。
我能想到的其他事情:
将onchange: '@'
之类的内容添加到指令的scope
属性中,然后在html中设置onchange = refresh
。在delete
函数内调用onchange表达式而不是刷新。但这感觉就像我重新实施ng-change
?
将require: '^AppController'
添加到指令中。然后我想我可以直接在父控制器上调用refresh
。这似乎违反了松耦合。
根本不使用隔离范围。这意味着我们从父作用域继承并且refresh
可用。但是,我的指令隐含地假设范围将包含item
。这也违反松散耦合,但是以隐含的方式。
所以我的问题是:让父控制器知道它应该刷新其内容的正确方法是什么?
答案 0 :(得分:2)
IMO,第一种方式是最好的方式。该指令从外部接收函数回调,必要时由指令执行。像这样,两个指令松散耦合。它与ng-change类似,ng-change是ng-model指令使用的属性。
示例:指令
app.directive('myItem', function() {
return {
restrict: 'E',
scope: {
item: '=data',
myItemDeleteCallback: '&myItemDeleteCallback'
},
template: '{{ item }} <button ng-click="delete(item)">-</button>',
controller: [ '$scope', '$http', function($scope, $http) {
$scope.delete = function (card) {
// This is where it goes wrong! refresh does not exist
$http.delete('/api/items' + card.id).then(function () {
$scope.myItemDeleteCallback();
});
}
}]
};
});
用法:控制器
app.controller('AppController', ['$scope', '$http', function ($scope, $http) {
$scope.list = [];
$scope.refresh = function (){
$http.get('/api/items').then(
function(response){
$scope.list = response.data;
}
);
};
$scope.add = function(item){
$http.post('/api/items', { item: item })
.then($scope.refresh);
};
refresh();
}]);
用法:模板
<div ng-cloak ng-controller="AppController">
<my-item my-item-delete-callback="refresh()" ng-repeat="item in list" data="list">
</my-item>
<input type="text" maxlength="50" ng-model="new_item" />
<button ng-click="add(new_item)">+</button>
</div>