所以,我有一个计数器($scope.counter
),我在ng-click
递增。我遇到的问题是我想从两个不同的控制器增加它,使计数器值保持同步。
controllerA.js
.controller('controllerA', controllerA);
function controllerA($scope) {
$scope.counter = 0;
function incrementCounter() {
$scope.counter = $scope.counter + 1;
}
...
controllerB.js
.controller('controllerB', controllerB);
function controllerB($scope) {
$scope.counter = 0;
function incrementCounter() {
$scope.counter = $scope.counter + 1;
}
...
当我在incrementCounter()
上拨打'controllerA'
时,它会更新'controllerA'
上的计数器,但不会更新'controllerB'
,反之亦然。
是否有一种正确的方法可以保持这些同步,无论我从哪个控制器调用incrementCounter()
函数?
感谢任何帮助。提前谢谢!
答案 0 :(得分:1)
这是服务派上用场的地方。
egghead.io有一个很好的视频:https://egghead.io/lessons/angularjs-sharing-data-between-controllers
他也谈到了很多关于ui-router的内容,但它也展示了如何使用服务。
<强>更新强>
如果您希望在两个控制器中即时更新该值,您可以观看该服务。
http://jsfiddle.net/jkrielaars/1swyy6re/2/
app.service('counterService', function() {
this.counter = 0;
this.addOne = function(){
this.counter++;
}
this.getCounter = function(){
return this.counter;
}
});
//Controllers
app.controller("controller1",function($scope, counterService){
$scope.counterService = counterService;
$scope.$watch('counterService.getCounter()', function (newVal) {
$scope.counter = newVal;
});
$scope.addOne = function(){
counterService.addOne();
}
})
app.controller("controller2",function($scope, counterService){
//same internals as controller 1
})
在您的视图中,您现在可以拥有两个同时更新的控制器
<div ng-controller="controller1">
counter value: {{counter}}
<button ng-click="addOne()">add 1</button>
</div>
<div ng-controller="controller2">
counter value: {{counter}}
<button ng-click="addOne()">add 1</button>
</div>
答案 1 :(得分:1)
有两种解决方案。
$rootScope
代替$scope
。$scope.counter = 0
,然后在此父级中使用的子控制器(A,B)中更新$scope.counter
值。答案 2 :(得分:1)
服务是共享计数器变量的好方法。如果要避免监视使它们保持同步,请确保将变量定义为服务上对象的属性。如果您想根据评论使用$http
标注填充该值,则可以将该值初始设置为null。
app.service('MyService', ['$http', function($http) {
var service = {
counter: {
value: null
},
incrementCounter: incrementCounter,
fetchTotal: fetchTotal
}
return service;
function incrementCounter(){
service.counter.value++;
}
function fetchTotal(url, p) {
$http.get(url, { params: p })
.then(function(response) {
service.counter.value = response.data.meta.total;
}, function(error) {
console.log("error occurred");
});
}
}]);
然后将counter
对象指定为控制器中$scope
的属性,并调用该服务以执行$http
标注:
app.controller('Controller1', function ($scope, MyService) {
$scope.counter = MyService.counter;
$scope.incrementCounter = function(){
MyService.incrementCounter();
}
fetchTotal('/test', '');
});
将counter
对象指定为$scope
上的属性可确保在视图中确保双向绑定完好无损。您可以使用ng-if
,这样您就不会渲染任何内容,直到$http
来电完成并且计数器已初始化。
<div ng-controller="Controller1">
<div ng-if="counter.value">
{{counter.value}}
<span ng-click="incrementCounter()">increment</span>
</div>
</div>
带有模拟$httpBackend
的答案 3 :(得分:0)
您还可以使用事件广播来更新其他控制器中的值。 Here是如何做到的:
app.controller('MainCtrl', function($scope, $rootScope) {
$scope.name = 'World';
$scope.counter = 0;
$scope.incrementCounter = function() {
$scope.counter++;
$rootScope.$broadcast('incrementedInController1', $scope.counter);
}
$scope.$on('incrementedInController2', function(event, newValueCounter) {
$scope.counter = newValueCounter;
});
}).controller('MainCtrl2', function($scope, $rootScope) {
$scope.name2 = 'World2';
$scope.counter = 0;
$scope.incrementCounter = function() {
$scope.counter++;
$rootScope.$broadcast('incrementedInController2', $scope.counter);
}
$scope.$on('incrementedInController1', function(event, newValueCounter) {
$scope.counter = newValueCounter;
});
});
答案 4 :(得分:0)
您可以使用可以从所有控制器访问的MeshBasicMaterial
,但由于存在问题,不推荐使用它。
$rootScope
如果您使用的是所有控制器之间的通用内容,建议您使用.controller('controllerA', controllerA);
function controllerA($rootScope) {
$rootScope.counter = 0;
}
.controller('controllerB', controllerA);
function controllerB($rootScope) {
$rootScope.counter = 1;
}
或Service
这是一个何时使用它的示例: http://viralpatel.net/blogs/angularjs-service-factory-tutorial/