在AngularJS中设置$ watch到服务函数的返回值

时间:2015-09-19 14:30:21

标签: angularjs angularjs-scope angularjs-service

TL; DR 如何在控制器中设置$watch到DI服务的功能返回值?

我的应用程序有一项服务,以便在控制器之间轻松共享数据。我试图从控制器设置$watch到其中一个变量。但是,我想通过服务的getter访问该特定变量。

这是控制器中的代码

    //this is the controller
    var vm = this;
    vm.isValidPhase = false;

    activate();

    ////////////////

    function activate() {
        vm.isValidPhase = userProgressService.getCurrentPhaseValidity();

        $scope.$watch('userProgressService.getCurrentPhaseValidity()',
                     function(newValue) {
            vm.isValidPhase = newValue;
        });
    }

userProgressService我有:

   //this is the service
   var current = {
        phaseNumber : 0,
        phaseValidity : false,
        phase   : {},
        userInput   : {}
    };

    // ... ... ...

    var exports = {
        getCurrentPhaseData  : getCurrentPhaseData,
        getCurrentPhaseValidity : getCurrentPhaseValidity,
        setCurrentPhaseValidity : setCurrentPhaseValidity,
        getExistingUserInput : getExistingUserInput
    };

    return exports;

    // ... ... ...

    function getCurrentPhaseValidity() {
        return current.phaseValidity;
    }

    // ... ... ...

在我使用 mocha,bard,chai sinon 对控制器进行的单元测试中,我正在做:

describe('initial state', function () {
    it('should be an invalid phase', function () {
        expect(userProgressService.getCurrentPhaseValidity(),
               'in service function').to.be.false;
        expect(controller.isValidPhase,
               'in controller scope').to.be.false;
    });
});

我在第二个断言中遇到错误:

AssertionError: in controller scope: expected undefined to be false

现在,通过评论和取消注释,我发现问题来自控制器中的$watch表达式。但我不知道它有什么问题......我做错了什么?

1 个答案:

答案 0 :(得分:0)

正如你在评论中看到的那样,@ JBNizet指出$watch表达式是错误的,相反,我应该正在观察函数本身,因为$scope中没有定义服务。但是,他也让我意识到,至少在这种情况下,我不需要设置$watch。用他自己的话说

  

[...]公开范围内服务的功能(即   $scope.getCurrentPhaseValidity = userProgressService.getCurrentPhaseValidity;),然后使用<button ng-show="getCurrentPhaseValidity()">

我告诉他并将控制器范围更改为

//... controller ...
vm.isValidPhase = userProgressService.getCurrentPhaseValidity;

现在我可以在控制器下的HTML中使用ng-showisValidPhase一样。

正如预期的那样,它工作并符合我想要观察变量的目的,即根据其值激活/停用按钮。

对于我能想到的,这个解决方案涵盖了您对此所遇到的许多相关问题。