参考this在Angular2/Typescript传回调
Pass callback in Angular2/Typescript with reference to this
在 Angular2 中传递实例方法。
在以下代码中从模板调用 login()
时,出现此错误:
Failure TypeError: Cannot read property 'router' of null
at AuthLoginComponent.success (auth-login.component.ts:30)
at ZoneDelegate.invoke (zone.js:242)
at Object.onInvoke (core.umd.js:4391)
at ZoneDelegate.invoke (zone.js:241)
at Zone.run (zone.js:113)
at zone.js:520
at ZoneDelegate.invokeTask (zone.js:275)
at Object.onInvokeTask (core.umd.js:4382)
at ZoneDelegate.invokeTask (zone.js:274)
at Zone.runTask (zone.js:151)
at drainMicroTaskQueue (zone.js:418)
at XMLHttpRequest.ZoneTask.invoke (zone.js:349)
在下面的代码中:
@Component({
moduleId: module.id,
selector: "app-auth-login",
templateUrl: "/app/components/auth/login/auth-login.component.html"
})
export class AuthLoginComponent implements OnInit {
username : "";
password : "";
constructor(
private authLoginService: AuthLoginService,
private router: Router
) {}
ngOnInit(): void {
}
success(value: Response) : void {
console.log("Success", value);
this.router.navigate(["/home"]);
}
failure(value: Response) : void {
console.log("Failure", value);
}
login() : void {
this.authLoginService.login(
this.username,
this.password,
this.success,
this.failure
)
}
}
我尝试传递 this
和 success
,然后在服务中调用 t[success]()
,但这会产生完全相同的错误。
我的服务使用断路器模式实现客户端 "load balancer",这就是为什么我通过 success/failure 函数来尽可能重用我的代码的原因。
该服务正在使用 rxjs
和 toPromise
,例如
httpService(...).toPromise().then(success).catch(response => {(circuit breaker pattern on some failures)})
您需要绑定this
,否则回调中的this
将指向调用者。
login() : void {
this.authLoginService.login(
this.username,
this.password,
this.success.bind(this),
this.failure.bind(this)
)
}
另一种方法是使用箭头函数
login() : void {
this.authLoginService.login(
this.username,
this.password,
(value) => this.success(value),
(value) => this.failure(value)
)
}
按设计应用作回调的方法可以绑定到其定义的上下文。这样他们就不可能在没有适当上下文的情况下被意外传递。
这可以用箭头实现:
success = (value: Response) : void => { ... }
或者在构造函数中绑定方法:
constructor(...) {
this.success = this.success.bind(this);
...
}
第二种方式有一个优势,它允许spy/mock方法作为AuthLoginComponent.prototype.success
。
在 Angular2 中传递实例方法。
在以下代码中从模板调用 login()
时,出现此错误:
Failure TypeError: Cannot read property 'router' of null
at AuthLoginComponent.success (auth-login.component.ts:30)
at ZoneDelegate.invoke (zone.js:242)
at Object.onInvoke (core.umd.js:4391)
at ZoneDelegate.invoke (zone.js:241)
at Zone.run (zone.js:113)
at zone.js:520
at ZoneDelegate.invokeTask (zone.js:275)
at Object.onInvokeTask (core.umd.js:4382)
at ZoneDelegate.invokeTask (zone.js:274)
at Zone.runTask (zone.js:151)
at drainMicroTaskQueue (zone.js:418)
at XMLHttpRequest.ZoneTask.invoke (zone.js:349)
在下面的代码中:
@Component({
moduleId: module.id,
selector: "app-auth-login",
templateUrl: "/app/components/auth/login/auth-login.component.html"
})
export class AuthLoginComponent implements OnInit {
username : "";
password : "";
constructor(
private authLoginService: AuthLoginService,
private router: Router
) {}
ngOnInit(): void {
}
success(value: Response) : void {
console.log("Success", value);
this.router.navigate(["/home"]);
}
failure(value: Response) : void {
console.log("Failure", value);
}
login() : void {
this.authLoginService.login(
this.username,
this.password,
this.success,
this.failure
)
}
}
我尝试传递 this
和 success
,然后在服务中调用 t[success]()
,但这会产生完全相同的错误。
我的服务使用断路器模式实现客户端 "load balancer",这就是为什么我通过 success/failure 函数来尽可能重用我的代码的原因。
该服务正在使用 rxjs
和 toPromise
,例如
httpService(...).toPromise().then(success).catch(response => {(circuit breaker pattern on some failures)})
您需要绑定this
,否则回调中的this
将指向调用者。
login() : void {
this.authLoginService.login(
this.username,
this.password,
this.success.bind(this),
this.failure.bind(this)
)
}
另一种方法是使用箭头函数
login() : void {
this.authLoginService.login(
this.username,
this.password,
(value) => this.success(value),
(value) => this.failure(value)
)
}
按设计应用作回调的方法可以绑定到其定义的上下文。这样他们就不可能在没有适当上下文的情况下被意外传递。
这可以用箭头实现:
success = (value: Response) : void => { ... }
或者在构造函数中绑定方法:
constructor(...) {
this.success = this.success.bind(this);
...
}
第二种方式有一个优势,它允许spy/mock方法作为AuthLoginComponent.prototype.success
。