2017-01-17 3 views
2

Способ передачи экземпляра в Angular2.Передать обратный вызов в Angular2/Typcript со ссылкой на это

При вызове 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](), но при этом возникает такая же ошибка.

Мой сервис реализует «балансировщик нагрузки» на стороне клиента с шаблоном автоматического выключателя, поэтому я передаю функцию успеха/отказа, чтобы как можно больше использовать мой код.

Услуга использует rxjs с toPromise, например. httpService(...).toPromise().then(success).catch(response => {(circuit breaker pattern on some failures)})

+0

Вам необходимо передать 'res => this.success (res)' – jonrsharpe

ответ

7

Вы должны связать 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) 
    ) 
} 
4

методы, которые должны быть использованы в качестве обратных вызовов по конструкции могут быть связаны с контекстом по их определению. Таким образом, нет никаких шансов, что они будут случайно пройдены без надлежащего контекста.

Это может быть достигнут со стрелкой:

success = (value: Response) : void => { ... } 

Или путем связывание методы в конструкторе:

constructor(...) { 
    this.success = this.success.bind(this); 
    ... 
} 

Второй способ имеет преимущество, что позволяет следить/макет метода как AuthLoginComponent.prototype.success.

Смежные вопросы