我正试图围绕如何一起使用Typescript和Angularjs。我已经阅读了几篇博客文章和两个项目的文档,但它并没有坚持下去。
我有一个Angular控制器,它接受两个依赖项,$ scope和我写的一个名为greetingService的服务。我已经定义了一个主应用程序Angular模块并将控制器和服务附加到它。我在我的Typescript构造函数中有日志语句,以便我可以检查浏览器中的依赖项。在我的控制器和我的自定义服务的构造函数中,正确地注入依赖项。但是,在控制器中,当我尝试使用依赖项时,它是未定义的。我认为这个代码片段比我能解释的更好地展示了这个问题。
declare var angular;
module App.Services {
export class GreetingService {
constructor(private $http) {
console.log("In greeting service constructor");
console.log($http);
}
getGreetingsPromise() {
return this.$http.get('/greetings.json');
}
}
}
module App.Controllers {
export class GreetingController {
static $inject = ['$scope', 'greetingService'];
constructor(public $scope, public greetingService: App.Services.GreetingService) {
this.$scope.greeting = "This will be a greeting.";
this.$scope.greet = this.greet;
console.log(greetingService); // this is defined and looks right
}
greet(language: string) {
console.log("Greeting...");
console.log(this.$scope); // this is undefined
console.log(this.greetingService); // this is undefined
var greetingPromise = this.greetingService.getGreetingsPromise();
greetingPromise.then(data => this.$scope.greeting = data[language]);
}
}
}
var mainApp = angular.module('mainApp', []);
mainApp.controller('greetingController', ['$scope', 'greetingService', App.Controllers.GreetingController]);
mainApp.service('greetingService', App.Services.GreetingService);
这是Angular模板(正确显示在构造函数中初始化的“这将是一个问候语”)。
<div class="jumbotron">
<div ng-controller="greetingController">
<p class="lead">{{greeting}}</p>
<button ng-click="greet('english')">Greet me</button>
</div>
</div>
答案 0 :(得分:3)
这一行:
this.$scope.greet = this.greet
是问题所在。您只是将函数引用复制到作用域属性,并且在使用作用域this
调用它时将不是控制器实例,它由调用者确定(在您的情况下,this
应该是除了绑定函数之外,在从模板调用时,greet
函数内的范围本身。快速解决方法是使用function.bind。即this.$scope.greet = this.greet.bind(this)
,您可以使用它创建绑定函数,绑定到控制器实例的函数引用。您还可以使用箭头函数并将其指定为引用,这将强制TS将任何this
转换为_this
缓存变量:
greet = (language: string) => {
console.log("Greeting...");
console.log(this.$scope); // this is undefined
console.log(this.greetingService); // this is undefined
var greetingPromise = this.greetingService.getGreetingsPromise();
greetingPromise.then(data => this.$scope.greeting = data[language]);
}
理想情况下,如果您使用controller As
(如果您的角度支持它,如果不强烈建议升级)语法而不是直接使用范围,则不需要执行所有这些操作。
即:
export class GreetingController {
greeting :string;
static $inject = ['greetingService'];
constructor(public greetingService: App.Services.GreetingService) {
this.greeting = "This will be a greeting.";
}
greet(language: string) {
var greetingPromise = this.greetingService.getGreetingsPromise();
greetingPromise.then(data => this.greeting = data[language]);
}
}
和
<div class="jumbotron">
<div ng-controller="greetingController as vm">
<p class="lead">{{vm.greeting}}</p>
<button ng-click="vm.greet('english')">Greet me</button>
</div>
</div>