在两个控制器之间更新$ scope

时间:2014-02-14 12:02:10

标签: javascript angularjs angularjs-scope

这很难解释,但我会尝试,请记住这一点。

我正在构建angularJS应用程序,但我无法更新UI($ scope)。

请参阅此处的布局 enter image description here

您是否可以同时看到有2个控制器和3个不同的$ scope。 例如,如果我在$ scope3中编辑“标题”,则“标题”也应该在$ scope2中更改。

监视更改的最佳方法是什么,在控制器之间传输值并将其传递到$ scope.value或强制新的$ resource调用。

我完全迷失在这里。

1 个答案:

答案 0 :(得分:4)

有多种方法可供选择。应该根据范围之间的关系选择最好的,如果它们在不同的模板或模块中等等。

首先,创建一个可以存储必要值的中介服务。这个中介服务可以在任何需要的地方注入 - 控制器,其他服务,指令。

模块1中的模板1

<div ng-controller="Ctrl1">
  <input type="text" ng-model="val">{{ val }}
</div>

模块1中的控制器1

app.controller('Ctrl1', ['$scope', 'ValMediator', function($scope, ValMediator) {
 $scope.val = '';

 $scope.$watch(
   function(){
     return ValMediator.getVal();
   },
   function(newVal){
     $scope.val = newVal;
   }
 );

 $scope.$watch('val',
   function(newVal){
     ValMediator.setVal(newVal);
   }
 );

}]);

模块2中的模板2

<div ng-controller="Ctrl2">
  <input type="text" ng-model="val">{{ val }}
</div>  

模块2中的控制器2

app.controller('Ctrl2', ['$scope', 'ValMediator',function($scope, ValMediator) {
  $scope.val = '';

  $scope.$watch(
    function(){
      return ValMediator.getVal();
    },
    function(newVal){
      $scope.val = newVal;
    }
  );

  $scope.$watch('val',
    function(newVal){
      ValMediator.setVal(newVal);
  }
 );

 }]);

调解员服务

app.factory('ValMediator', function() {
  var val = '';
  return {
    setVal: function(newVal){
      val = newVal;
    },
    getVal: function(){
      return val;
    }
  };
});

请参阅此 first jsBin example ValMediator是此类服务的示例,它将val变量存储在内部,并将getter和setter公开为公共接口。其他控制器可以注入并使用。通过在服务获取器上使用$scope.$watch,所有外部更改都将放入本地$scope。观察本地val用于通过中介服务将本地更改发布给其他使用者。

=====================

另一种方法是通过$rootScope发出事件。我不认为应该使用这种方法,因为它会使rootScope包含不必要的事件。但是,它是交叉模块/范围通信的有效方法,应予以考虑。

请参阅second jsBin example

此处,调解员的角色由$rootScope服务承担,该服务仅用作事件传输的媒介。模板是相同的,但控制器除了$scope$rootScope之外不需要任何其他内容进行通信:

控制器1模块1

app.controller('Ctrl1', ['$scope', '$rootScope', function($scope, $rootScope) {
  $scope.val = '';

  $scope.$on('Val/update', function(e, arg){
    console.log('val update 1', arg);
    $scope.val = arg;
  });

  $scope.$watch('val',
    function(newVal, oldVal){
      if (newVal === oldVal) return;
      $rootScope.$broadcast('Val/update', newVal);
  }
);

}]);

控制器2模块2

app.controller('Ctrl2', ['$scope', '$rootScope',function($scope, $rootScope) {
  $scope.val = '';

  $scope.$on('Val/update', function(e, arg) {
    console.log('val update 2', arg);
    $scope.val = arg;
  });

  $scope.$watch('val',
    function(newVal, oldVal) {
      if (newVal === oldVal) return;
      $rootScope.$broadcast('Val/update', newVal);
    }
  );

}]);

这是第二个例子 - 只是对变更事件作出反应并发布你自己的更新