控制器在点击时更改另一个控制器的数据

时间:2016-02-26 10:45:24

标签: javascript angularjs

我想通过onClick - 事件将一些数据从一个控制器传递到第二个控制器。我试图在两个控制器之间使用服务,但似乎从服务接收数据的控制器不能识别第一个控制器的onClick - 事件导致静态/非变化数据。

OnClick功能(控制器1)

$scope.select = function(index){            
    vm.currentActive = index;
    sessionService.setState(index);         
};

兑换服务

app.service('sessionService', function() {


    var state = null;

    var setState = function(changestate){
        state = changestate;
    };

    var getState = function(){
        return state;
    };

    return {

        setState: function(changestate){
            setState(changestate);
        },
        getState: function(){
            return state;
        }
    };
});

接收控制器(控制器2)

app.controller('ContentController', function ($scope, sessionService)
{       
    var vm = this;
    vm.currentActive = sessionService.getState();
});

最后,我希望只要在控制器1中触发OnClick - 事件,控制器2的状态就会发生变化。这种方式对服务是最好的还是建议更改控制器2中的数据后点击一下?

3 个答案:

答案 0 :(得分:1)

观察服务状态的一个选项是使用$scope.$watch函数返回要监视更改的值。

$scope.$watch(function(){ return sessionService.getState(); }, function(newValue, oldValue){
    //Do something
});

如果更改了服务中的值,手表将在下一个摘要周期中获取更改。使用此方法,无需让您的服务或其他控制器尝试并发出值已更改的信号。

如果你的服务的getter方法不依赖于this,你可以通过将getter方法作为watch函数传递而不是使用包装函数来简化观察者。

$scope.$watch(sessionService.getState, function(newValue, oldValue){
    //Do something
});

答案 1 :(得分:0)

您可以将onChange事件添加到服务:

app.service('sessionService', function() {

    var state = null;
    var callbacks = [];

    var setState = function(changestate) {
        callbacks.forEach(function(callback) {
            callback(state, changestate);
        });
        state = changestate;
    };

    var getState = function() {
        return state;
    };

    return {
        setState: function(changestate) {
            setState(changestate);
        },
        getState: function() {
            return state;
        },
        onChange: function(fn) {
            if (typeof fn == 'function') {
                callbacks.push(fn);
            }
        }
    };
});

答案 2 :(得分:0)

接收控制器没有获得更新值的原因是因为state属性在指令定义对象初始化时被复制vm.state

vm.currentActive = sessionService.getState();

此处getState只调用一次,因此稍后更新state值无关紧要......

一种解决方案

一个选项是从控制器的视图中调用getState(将在每个摘要周期中重新调用(即值将更新))...注意此策略具有性能影响...

另一种解决方案

另一种选择是利用引用对象的涓滴效应(或者像Miško在这个Angular Best Practices video中解释的那样,“......如果你没有一个点,你做错了...... “

您可以通过使用对象在Exchange服务中存储状态来利用此策略...

app.service('sessionService', function() {

  var data = {};

  var setState = function(changestate){
    data.state = changestate;
  };

  var getState = function(){
    return data.state;
  };

  return {
    setState: setState,
    data: data
  };
});

接收控制器

app.controller('ContentController', function ($scope, sessionService) {       
  var vm = this;
  vm.data = sessionService.data;
});

然后,只要在data.state中更新sessionServicevm.data.state(凭借引用的数据)也会包含更新的数据。

换句话说,vm.data.state将始终包含最新值sessionService.data.state,因为它们都引用同一个对象。