Angularjs:'控制器作为语法'和$ watch
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Angularjs:'控制器作为语法'和$ watch相关的知识,希望对你有一定的参考价值。
使用controller as
语法时如何订阅属性更改?
controller('TestCtrl', function ($scope) {
this.name = 'Max';
this.changeName = function () {
this.name = new Date();
}
// not working
$scope.$watch("name",function(value){
console.log(value)
});
});
<div ng-controller="TestCtrl as test">
<input type="text" ng-model="test.name" />
<a ng-click="test.changeName()" href="#">Change Name</a>
</div>
只需绑定相关的上下文。
$scope.$watch(angular.bind(this, function () {
return this.name;
}), function (newVal) {
console.log('Name changed to ' + newVal);
});
示例:http://jsbin.com/yinadoce/1/edit
更新:
Bogdan Gersak的回答实际上是等同的,两个答案尝试用正确的语境绑定this
。但是,我发现他的答案更清晰。
说到这一点,首先,你必须了解the underlying idea behind it。
更新2:
对于那些使用ES6的人来说,通过使用arrow function
,您可以获得具有正确上下文OOTB的功能。
$scope.$watch(() => this.name, function (newVal) {
console.log('Name changed to ' + newVal);
});
这是你如何做到这一点没有$ scope(和$ watch!)Top 5 Mistakes - Abusing watch
如果您使用“控制器为”语法,则避免使用$ scope更好更清洁。
这是我在JSFiddle的代码。 (我使用服务来保存名称,否则ES5 Object.defineProperty的set和get方法会导致无限次调用。
var app = angular.module('my-module', []);
app.factory('testService', function() {
var name = 'Max';
var getName = function() {
return name;
}
var setName = function(val) {
name = val;
}
return {getName:getName, setName:setName};
});
app.controller('TestCtrl', function (testService) {
var vm = this;
vm.changeName = function () {
vm.name = new Date();
}
Object.defineProperty(this, "name", {
enumerable: true,
configurable: false,
get: function() {
return testService.getName();
},
set: function (val) {
testService.setName(val);
console.log(vm.name);
}
});
});
我经常这样做:
controller('TestCtrl', function ($scope) {
var self = this;
this.name = 'Max';
this.changeName = function () {
this.name = new Date();
}
$scope.$watch(function () {
return self.name;
},function(value){
console.log(value)
});
});
您可以使用:
$scope.$watch("test.name",function(value){
console.log(value)
});
这是你的例子JSFiddle。
与使用“TestCtrl as test”中的“test”类似,如另一个答案中所述,您可以为您的范围指定“self”:
controller('TestCtrl', function($scope){
var self = this;
$scope.self = self;
self.name = 'max';
self.changeName = function(){
self.name = new Date();
}
$scope.$watch("self.name",function(value){
console.log(value)
});
})
通过这种方式,您不依赖于DOM中指定的名称(“TestCtrl as test”),也避免了.bind(this)对函数的需要。
...用于指定的原始html:
<div ng-controller="TestCtrl as test">
<input type="text" ng-model="test.name" />
<a ng-click="test.changeName()" href="#">Change Name</a>
</div>
AngularJs 1.5支持ControllerAs结构的默认$ ctrl。
$scope.$watch("$ctrl.name", (value) => {
console.log(value)
});
你实际上可以传入一个函数作为$ watch()的第一个参数:
app.controller('TestCtrl', function ($scope) {
this.name = 'Max';
// hmmm, a function
$scope.$watch(function () {}, function (value){ console.log(value) });
});
这意味着我们可以返回我们的this.name参考:
app.controller('TestCtrl', function ($scope) {
this.name = 'Max';
// boom
$scope.$watch(angular.bind(this, function () {
return this.name; // `this` IS the `this` above!!
}), function (value) {
console.log(value);
});
});
阅读有关控制器主题https://toddmotto.com/digging-into-angulars-controller-as-syntax/的有趣帖子
您可以使用$ onChanges角度组件生命周期。
请参阅此处的文档:基于组件的应用程序部分下的https://docs.angularjs.org/guide/component
用ES6语法编写$ watch并不像我预期的那么容易。这是你可以做的:
// Assuming
// controllerAs: "ctrl"
// or
// ng-controller="MyCtrl as ctrl"
export class MyCtrl {
constructor ($scope) {
'ngInject';
this.foo = 10;
// Option 1
$scope.$watch('ctrl.foo', this.watchChanges());
// Option 2
$scope.$watch(() => this.foo, this.watchChanges());
}
watchChanges() {
return (newValue, oldValue) => {
console.log('new', newValue);
}
}
}
注意:当View和Controller在路由中耦合或通过指令定义对象时,这不起作用。下面显示的内容仅在HTML中有“SomeController as SomeCtrl”时才有效。就像Mark V.在下面的评论中指出的那样,正如他所说的那样,像波格丹那样做得更好。
我在控制器的开头使用:var vm = this;
来获取“this”这个词。然后vm.name = 'Max';
和手表我return vm.name
。我使用“vm”就像@Bogdan使用“self”一样。这个var,无论是“vm”还是“self”都需要,因为单词“this”在函数内部采用不同的上下文。 (所以返回this.name是行不通的)是的,你需要在美丽的“控制器作为”解决方案中注入$ scope以达到$ watch。请参阅John Papa的风格指南:https://github.com/johnpapa/angularjs-styleguide#controllers
function SomeController($scope, $log) {
var vm = this;
vm.name = 'Max';
$scope.$watch('vm.name', function(current, original) {
$log.info('vm.name was %s', original);
$log.info('vm.name is now %s', current);
});
}
以上是关于Angularjs:'控制器作为语法'和$ watch的主要内容,如果未能解决你的问题,请参考以下文章
AngularJs - 使用“控制器作为”语法的 ag-grid rowData
AngularJS之基础-3 控制器(基本语法)模块(使用模块注册控制器)
错误:[$ parse:syntax]语法错误:令牌'{'是一个意外的令牌