使用AngularJS中的标准控制器语法,您可以观察如下变量:
$scope.$watch(somethingToWatch, function() { alert('It changed!'); });
使用controllerAs语法,我想对活动控制器中的此更改做出反应。最简单的方法是什么?
更多细节,如果有帮助的话。我在侧窗格中有一个控制器来控制应用程序的上下文(用户选择,开始时间,结束时间等)。因此,如果用户更改为不同的上下文,主视图应该做出反应并更新。我将上下文值存储在工厂中,每个控制器都注入该工厂。
答案 0 :(得分:5)
您始终可以使用观察者评估程序功能,尤其有助于在控制器实例或任何对象上观察某些内容。你实际上可以返回任何变量。
var vm = this;
//Where vm is the cached controller instance.
$scope.$watch(function(){
return vm.propToWatch;
}, function() {
//Do something
}, true);//<-- turn on this if needed for deep watch
还有一些方法可以使用绑定函数来绑定this
上下文。
$scope.$watch(angular.bind(this, function(){
return this.propToWatch;
//For a variable just return the variable here
}), listenerFn);
甚至是ES5 function.bind:
$scope.$watch((function(){
return this.propToWatch;
}).bind(this), listenerFn);
如果你处于打字稿世界,它会变得更短。
$scope.$watch(()=> this.propToWatch, listenerFn);
尽管你可以看到控制器内的控制器别名($scope.watch('ctrlAs.someProp'
),但它会带来几个问题:
它预测(或换句话说,预先确定)视图/路由/指令/模态中控制器使用的别名或使用控制器的任何位置。它破坏了使用controllerAs:'anyVMAlias'
的目的,{{1}}也是可读性的重要因素。由于使用控制器需要知道实现中定义了什么名称,因此很容易造成拼写错误和维护问题。
当您对控制器(仅控制器)进行单元测试时,您需要再次使用控制器内部定义的完全相同的别名进行测试(如果您正在编写TDD,这可能是一个额外的步骤),理想情况下不应该在测试控制器时需要。
使用一个为字符串提供观察器功能的观察者总是减少一些步骤,角度$ parse(watch用来创建表达式)在内部将字符串表达式转换为watch函数。可以在$parse implementation