Angular JS:在控制器之间使用$ scope.variable

时间:2015-10-28 20:55:18

标签: angularjs controller angularjs-scope

所以,我有一个计数器($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()函数?

感谢任何帮助。提前谢谢!

5 个答案:

答案 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)

有两种解决方案。

  1. 使用$rootScope代替$scope
  2. 拥有父控制器并在其中定义$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

Fiddle

答案 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/

相关问题