Передайте обратный вызов в Angular2 / Typescript со ссылкой на это
Передача метода экземпляра в 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]()
в службе, но это приводит к точно такой же ошибке.
В моем сервисе реализован клиентский "балансировщик нагрузки" с шаблоном автоматического выключателя, поэтому я передаю функцию success/failure для повторного использования моего кода как можно чаще. по возможности.
Служба использует rxjs
с toPromise
, например
httpService(...).toPromise().then(success).catch(response => {(circuit breaker pattern on some failures)})
2 ответа:
Нужно привязать
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); ... }
AuthLoginComponent.prototype.success
.