AngularJS 的作用域无法绑定到 TypeScript 类的 this,用于 controllerAs 语法
我正在尝试使用 AngularJS,并且我尝试使用 TypeScript 类为一个大型项目做准备。我遇到的问题是,控制器类的 this 没有绑定到 DOM 中 ng-controller 指令所在部分的 scope。
从以下 TypeScript 代码开始:
angular.module('testApp')
.controller('TypeScriptController', () => new TypeScriptController())
// Controller implementation via TypeScript
class TypeScriptController {
text = "Please click the button";
constructor() {}
buttonClick () {
this.text = "The button was clicked";
}
}
并将控制器绑定到 DOM 上
<main ng-controller="TypeScriptController as TSCtrl">
如果我使用标准的 ES5 函数风格实现,它可以正常工作(见下方代码片段的前半部分)。然而,类的版本则不行。现在我可以将 $scope 变量传递给控制器,并将 $scope 的某个属性绑定到 this,但 HTML 中的 controllerAs 语法将被忽略。不过,我希望能避免将 $scope 传递给每个控制器。
我知道 AngularJS 1.3 为指令引入了 bindToController 选项,但我不明白这在这种情况下如何使用。
示例:
在此示例中展示了控制器的 ES5 和 TypeScript 实现。控制器仅包含一个方法,ng-click 调用该方法在按钮下方写入文本。ES5 版本可用。TypeScript 版本不可用。我还在 Plunker 中实现了这个示例。
angular.module('testApp', [])
.controller('MainController', MainController);
function MainController() {
this.text = "Please click the button";
this.buttonClick = function() {
this.text = "The button was clicked";
};
};
// Compiled from TypeScript source
angular.module('testApp').controller('TypeScriptController', function() {
return new TypeScriptController();
});
// Controller implementation via TypeScript
var TypeScriptController = (function() {
function TypeScriptController() {
this.text = "Please click the button";
}
TypeScriptController.prototype.buttonClick = function() {
this.text = "The button was clicked";
};
return TypeScriptController;
})();<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<body ng-app="testApp">
<main ng-controller="MainController as mainCtrl">
<h1>Hello World!</h1>
<p>
<input type="button" name="testInput" value="Test button" ng-click="mainCtrl.buttonClick()">
</p>
<p>{{mainCtrl.text}}</p>
</main>
<main ng-controller="TypeScriptController as TSCtrl">
<h1>Hello TypeScript!</h1>
<p>
<input type="button" name="testInput" value="Test button" ng-click="TSCtrl.buttonClick()">
</p>
<p>{{TSCtrl.text}}</p>
</main>
</body>答案#1
如果你希望 buttonClick 成为实例成员(像你在 ES5 版本中那样)而不是原型成员,请使用箭头函数:
// Controller implementation via TypeScript
class TypeScriptController {
text = "Please click the button";
constructor() {}
// Arrow function captures 'this'
buttonClick = () => {
this.text = "The button was clicked";
}
}
答案#2
angular.module('testApp') .controller('TypeScriptController',() => new TypeScriptController())
你在 controllerAs 语法上弄错了。应该这样做:
angular.module('testApp')
.controller('TypeScriptController', TypeScriptController)
当 Angular 看到 controller as 时,会运行 new。
