【发布时间】:2015-09-30 05:41:14
【问题描述】:
请考虑以下代码:它有一个指令myItem 与隔离范围。每个项目将显示一个按钮,该按钮将在指令控制器上调用delete()。我希望这能在外部控制器 (AppController) 中触发 refresh。但是当然找不到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,这似乎有点过头了。
我能想到的其他事情:
在指令的
scope属性中添加类似onchange: '@'的内容,然后在html 中设置onchange = refresh。在delete函数内调用 onchange 表达式而不是刷新。但这感觉就像我在重新实现ng-change?将
require: '^AppController'添加到指令中。然后我想我可以直接在父控制器上调用refresh。这似乎违反了松散耦合。根本不要使用隔离作用域。这意味着我们从父作用域继承并且
refresh可用。但随后我的指令隐含地假定范围将包含item。这也违反了松散耦合,但是以隐含的方式。
所以我的问题是:让父控制器知道它应该刷新其内容的正确方法是什么?
【问题讨论】:
-
使用
$rootScope怎么样? -
@iam-decoder:我不知道
$rootScope并且无法快速找到很多有用的文档。对我有什么帮助? -
这个逻辑似乎是倒着实现的。您想向
delete发出服务器调用,然后立即告诉父控制器它应该向服务器发出get调用以确定该项目真的被删除了吗?有很多方法可以在不涉及两个单独的服务器调用的情况下处理删除项目...... -
事实上,在这种情况下,该指令根本不应该负责删除该项目。
-
替代方案包括使用服务来维护数据的状态,或使用
$broadcast允许应用程序的其他区域响应更改。一般来说,最好尽可能限制与服务器通信的组件。
标签: javascript angularjs