AngularJS:从另一个控制器/作用域更新控制器作用域
AngularJS:从另一个控制器/作用域更新控制器作用域
希望这个问题还没有被问过..我找了一下,还没有找到相关的内容。\n我有一个单一的视图,为用户提供一个模态对话框(向导),用于创建一些东西然后保存它们。似乎一切工作正常,除了视图使用ng-repeat列出创建的项时,当新项被推入列表时,视图不会更新。考虑下面的例子。\n
app.service('Utils', function() { }); function controller1($scope,Utils) { $scope.myList = []; Utils.add = function(obj) { $scope.myList.push(obj); } }; function controller2($scope,Utils) { var temp = {"name":"John Doe"}; Utils.add(temp); };
\n这非常基础,但足够了解我在做什么。$scope.myList在视图中使用ng-repeat显示。在某个时候,我会显示向导,经过创建新项的过程,然后将该项推入列表中。add函数是Utils服务的一部分,该服务还有其他用途,但不需要在这里详细说明。add函数在第一个控制器中声明,并可通过第二个控制器访问。创建新项并将其推入$scope.myList的操作正常工作。我可以查看第一个控制器的$scope,看到该变量包含一个新对象,但视图永远不会更新以显示它。\n有没有想法是什么导致视图不更新?有没有更好的方法来解决这个问题?我在其他地方找到了使用服务作为中介的建议,但如果有更好的方法也可以解决这个问题,我愿意尝试。
AngularJS中,我们有时候需要在一个控制器(Controller)中更新另一个控制器的作用域(Scope)。下面是一个示例,展示了这个问题的出现原因以及解决方法。
在这个示例中,我们有两个控制器:List1Ctrl和List2Ctrl。List1Ctrl控制器负责向一个列表中添加新的项目,而List2Ctrl控制器负责显示这个列表。
我们使用一个工厂(Factory)来创建一个共享的数据服务,名为Items。这个服务包含一个list数组,初始时包含一个名为"Apples"的项目。它还包含两个方法:add用于向列表中添加项目,get用于获取列表。
List1Ctrl控制器通过注入Items服务来获取列表,并且将列表赋值给$scope.items。它还定义了一个新的项目对象$scope.new_item,并且通过一个名为addItem的函数向列表中添加新的项目。添加完成后,它将$scope.new_item重置为空对象。
List2Ctrl控制器同样通过注入Items服务来获取列表,并且将列表赋值给$scope.items。
这个示例中的问题是,当我们在List1Ctrl控制器中添加新的项目时,List2Ctrl控制器的作用域并没有更新,导致列表不会显示新的项目。
解决这个问题的方法是使用AngularJS中的事件机制。我们可以在Items服务中定义一个事件,当有新的项目添加进来时,触发这个事件。然后,在List2Ctrl控制器中监听这个事件,并在事件触发时更新$scope.items。
下面是修改后的代码:
var app = angular.module('itemsApp', []); app.factory('Items', function ($rootScope) { var list = [{ name: 'Apples', color: 'Red' }]; return { add: function (item) { list.push(item); $rootScope.$broadcast('itemAdded'); }, get: function () { return list; } } }); app.controller('List1Ctrl', function ($scope, Items) { $scope.items = Items.get(); $scope.new_item = {}; $scope.addItem = function () { Items.add($scope.new_item); $scope.new_item = {}; } }); app.controller('List2Ctrl', function ($scope, Items) { $scope.items = Items.get(); $scope.$on('itemAdded', function () { $scope.items = Items.get(); }); });
在这个修改后的代码中,我们在Items服务中注入了$rootScope,并在add方法中通过$rootScope.$broadcast('itemAdded')来触发一个名为itemAdded的事件。
在List2Ctrl控制器中,我们使用$scope.$on('itemAdded', function () {...})来监听这个事件,并在事件触发时更新$scope.items。这样,当List1Ctrl控制器向列表中添加新的项目时,List2Ctrl控制器的作用域会自动更新,显示新的项目。
通过这个方法,我们可以实现在一个控制器中更新另一个控制器的作用域,解决了这个问题。