Angularjs: ‘ controller as language’and $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>
54007 次浏览

你可使用:

   $scope.$watch("test.name",function(value){
console.log(value)
});

这就是在你的例子中使用 JSFiddle

只要绑定相关的上下文。

$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。然而,我发现他的答案更干净。

也就是说,首先也是最重要的是,你必须理解 它背后的基本思想

更新2:

对于那些使用 ES6的人来说,通过使用 arrow function,您可以得到一个具有正确上下文 OOTB 的函数。

$scope.$watch(() => this.name, function (newVal) {
console.log('Name changed to ' + newVal);
});

例子

我通常这样做:

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)
});
});

与使用“ 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”) ,并且还可以避免需要。把(这个)绑定到一个函数上。

... 用于指定的原始 html:

<div ng-controller="TestCtrl as test">
<input type="text" ng-model="test.name" />
<a ng-click="test.changeName()" href="#">Change Name</a>
</div>

注意 : 当 View 和 Controller 在路由或通过指令定义对象耦合时,这不起作用。下面显示的内容只有在 HTML 中有一个“ Some Controller as Some Ctrl”时才能工作。就像 Mark V 在下面的评论中指出的,就像他说的,最好像 Bogdan 那样做。

我在控制器的开头使用: var vm = this;来除去“ this”这个单词。然后是 vm.name = 'Max';和手表中的 return vm.name。我用“ vm”就像@Bogdan 用“ self”一样。这个变量,不管是“ vm”还是“ self”都是必需的,因为单词“ This”在函数内部具有不同的上下文。(所以返回 this. name 不会起作用)是的,为了达到 $watch,需要在漂亮的“ controller as”解决方案中注入 $scope。参见约翰爸爸的风格指南: 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);
});
}

下面介绍如何在没有 $scope (和 $watch!) 五大错误-滥用手表的情况下完成此操作

如果使用“ controller as”语法,那么避免使用 $scope 会更好、更简洁。

这是我在 JSFiddle中的代码。(我使用一个服务来保存名称,否则 ES5 Object.defeProperty 的 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);
}
});
});

用 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);
}
}
}

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/

可以使用 $变化角组件生命周期。

点击这里查看文档: Https://docs.angularjs.org/guide/component 根据 基于组件的应用程序章节