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
表达式。但我不知道它有什么问题......我做错了什么?
答案 0 :(得分:0)
正如你在评论中看到的那样,@ JBNizet指出$watch
表达式是错误的,相反,我应该正在观察函数本身,因为$scope
中没有定义服务。但是,他也让我意识到,至少在这种情况下,我不需要设置$watch
。用他自己的话说
[...]公开范围内服务的功能(即
$scope.getCurrentPhaseValidity = userProgressService.getCurrentPhaseValidity;
),然后使用<button ng-show="getCurrentPhaseValidity()">
我告诉他并将控制器范围更改为
//... controller ...
vm.isValidPhase = userProgressService.getCurrentPhaseValidity;
现在我可以在控制器下的HTML中使用ng-show
和isValidPhase
一样。
正如预期的那样,它工作并符合我想要观察变量的目的,即根据其值激活/停用按钮。
对于我能想到的,这个解决方案涵盖了您对此所遇到的许多相关问题。