0

根据我的阅读,除非绝对必要,否则似乎不建议使用 $rootScope.$broadcast 。我在服务中使用它来通知控制器变量已更改。这是不正确的吗?有更好的方法吗?我应该改用 watch 吗(即使变量只在用户交互时发生变化)?

服务:

function Buildservice($rootScope) {
        var vm = this;
        vm.box= [];

    var service = {
        addItem: addItem,

    };
    return service;

    // Add item to the box
   // Called from a directive controller
    function addItem(item) {
        vm.box.push(item);
        broadcastUpdate();
    }

    function broadcastUpdate() {
        $rootScope.$broadcast('updateMe');
    }

// 在要通知的控制器中:

    // Listener for box updates
    $scope.$on('updateMe', function() {
        // update variable binded to this controller
    });

// 并且来自一个单独的指令控制器:

function directiveController($scope, buildservice) {

    function addToBox(item){
        buildservice.addItem(item);
    }

所以这对我来说很好,但我不知道这是否是我应该这样做的方式。感谢帮助!

4

2 回答 2

0

您可以使用回调函数来通知控制器发生了变化。您从控制器为服务提供一个函数,并在您的变量发生更改时调用该特定函数。如果需要,您还可以通知多个控制器。

我创建了一个小例子:

HMTL:

<div ng-controller="CtrlA as A">
  {{A.label}}
  <input type="text" ng-model="A.input" />
  <button ng-click="A.set()">set</button>
</div>
<div ng-controller="CtrlB as B">
  {{B.label}}
  <input type="text" ng-model="B.input" />
  <button ng-click="B.set()">set</button>
</div>

JS

var app = angular.module('plunker', []);

app.controller('CtrlA', function(AService) {
  var vm = this;
  vm.label = AService.get();

  vm.notify = function() {
    vm.label = AService.get();
  }

  vm.set = function() {
    AService.set(vm.input)
  }

  AService.register(vm.notify);
});

app.controller('CtrlB', function(AService) {
  var vm = this;
  vm.label = AService.get();

  vm.notify = function() {
    vm.label = AService.get();
  }

  vm.set = function() {
    AService.set(vm.input)
  }
  AService.register(vm.notify);
});



app.factory("AService", function() {

  var myVar = "Observer";
  var observers = [];

  return {
    get: function() {
      return myVar;
    },

    set: function(name) {
      console.log(name);
      myVar = name;
      this.notify();
    },

    register: function(fn) {
      observers.push(fn);
    },

    notify: function() {
      for( i = 0; i < observers.length; i++) { 
        observers[i]();
      }
    }
  }
})

您将在执行此操作时看到,当内部变量已更改时,控制器会收到通知。(注意:我没有从列表中过滤出原始发件人)(Plnkr

于 2015-12-15T15:35:41.463 回答
0

如果您在同一个模块中,为什么不使用 $scope 而不是 $rootScope?

于 2015-12-15T14:30:03.080 回答