繁体   English   中英

如何从Angular 4中的回调绑定

[英]How can I bind from a callback in Angular 4

我正在尝试将模板绑定到通过回调从订阅返回的值。 但是没有调用变更检测。

  //authorisation service public login(data,callbackFromLogin : (msg) => void): void { this.http.httpPost(ApiRoutes.LoginRoute,data).subscribe(result => { callbackFromLogin(msg); }); } //and then in login component onSubmit(request) { this.authService.login(request,(message) => { alert(NgZone.isInAngularZone()); if(message) { this.ngZone.run( () => { this.message = message; alert(NgZone.isInAngularZone()); }); } }); } 
 <div>{{message}}</div> 

该消息不会更改,尽管它会从服务获取值。 我想这个问题与区域有关。

我不知道为什么不会这样。

但是下面有一些问题。

谁将msg设置为回调?

也许你想做callbackFromLogin(result);

但是我认为您可以尝试实施另一种解决方案。

为什么您将回调传递给service而不在组件的订阅内部执行该函数?

像这样:

 // authorisation service
 public login(data) {
  return this.http.httpPost(ApiRoutes.LoginRoute, data);
  // if you want manipulate the message you could use `pipe` method here
 }

 // and then in login component 
 onSubmit(request) {
   this.authService.login().subscribe((message) => {
     if(message){
       this.message = message;
     }   
   });
 }

我使用了您的建议并将代码更改为此:

 //Service public login(data): Observable<any> { return this.http.httpPost(ApiRoutes.LoginRoute,data).pipe(map(result=>{ if (result && result.status == 200) { /// }else{ let msg = `my message`; return {msg:msg}; } })); } //login component onSubmit(request){ this.authService.login(request).subscribe((result) => { if(result.msg){ this.message = result.msg; alert( this.message ) } }); } 
 <div>{{message}}</div> 

同样的问题,消息传递给结果,当我调用alert(this.message)函数时,消息显示在上方。但是模板插值没有变化。

试试这个,让我知道。

  1. 设置属性loginRequest: Observable<any>;
  2. onSubmit()内部:

onSubmit(request){ this.loginRequest = this.authService.login(request); }

在您的模板中

<div> 
  {{ (loginRequest | async)?.msg }}
</div>

这是一个简单的Http调用。

import {HttpClient} from '@angular/common/http';

class SomeService {
  constructor(private _http: HttpClient){}

  postSomething() {
    return this._http.post('url', toPost);
  }
}

是的。这里是AuthService:

 import { SessionService } from '../session/session.service'; import { environment } from './../../../environments/environment'; import { IUser, UserType } from '../../../../../contracts/IUser'; import { IEmployee } from '../../../../../contracts/IEmployee'; import { Injectable,Inject } from '@angular/core'; import { Router } from '@angular/router'; import 'rxjs/add/operator/filter'; import * as auth0 from 'auth0-js'; import { Http } from '@angular/http'; import {ReplaySubject, Observable} from 'rxjs/Rx'; import { ApiService } from '../api/api.service'; import { ActivityService } from '../activity/activity.service'; import { UserActivityAction } from '../../../../../contracts/Library'; import { ApiRoutes } from '../../../../../contracts/ApiRoutes'; import { AlertService} from '../alert/alert.service'; import { MessageService} from '../message/message.service'; import {Events} from '../../../../../contracts/Library'; import { map } from 'rxjs/operators'; @Injectable() export class AuthService { private userIsLoggedIn : boolean; constructor(public http: ApiService,private rHttp: Http, private session:SessionService, @Inject('BASE_URL') public baseUrl: string, public router: Router, private alertService: AlertService, private activity: ActivityService, private messageService : MessageService) { this.session = session; } // logIn attempts to log in a user handleAuthentication() : void { let auth = this.http.httpGetAll(ApiRoutes.AuthRoute); auth.subscribe( data => { let results = data.json(); switch(results.status) { case 401: { this.routeAfterLogin(false); this.messageService.sendMessage('',Events.UserLogout); break; } case 402: { break; } case 200: { //when success break; } default: { this.routeAfterLogin(false); break; } } }, error => { console.log(error); }); this.router.navigate(['/home']); } public login(data): Observable<any> { return this.http.httpPost(ApiRoutes.LoginRoute,data).pipe(map(result=>{ if (result && result.status == 200) { //when success }else{ let msg = "some error message"; this.routeAfterLogin(false); return {msg:msg}; } })); } private routeAfterLogin(state:boolean) { this.userIsLoggedIn = state; if(this.userIsLoggedIn){ this.router.navigate(['/home']); console.log("Login"); } else { this.router.navigate(['/login']); console.log("Failure Login"); } } public logout(): void { let auth = this.http.httpGetAll(ApiRoutes.LogoutRoute); auth.subscribe( data => { console.log("Logout"); this.messageService.sendMessage('',Events.UserLogout); this.router.navigate(['/login']); }, error => { console.log(error); }); } public isAuthenticated(): boolean { return this.userIsLoggedIn; } public fillFileDownloadPass(){ let getUploadPath$ = this.http.httpGetAll(ApiRoutes.DownloaPathdRout); getUploadPath$.subscribe( data => { let results = data.json(); switch(results.status) { case 200: { this.session.download101AtchFilePath = results.filehDownloadPat; this.session.approvedFormsPath = results.approvedFormsPath; break; } case 400: { console.log("didn't find an upload path"); break; } default: { break; } } }, error => { console.log(error); }); } } 

从app.component。中调用handleAuthentication()函数。

  ngOnInit() { this.authService.handleAuthentication(); this.subscription = this.messageService.getMessage().subscribe(message => { switch (message.type) { case Events.UserLogin: this.showNav = true; break; case Events.UserLogout: this.showNav = false; break; case Events.FirstEntrance : //some message break; } }); } 

ApiService的httpPost函数包装http:

  httpPost(url:string,data:any):Observable<Response | any> { return this._http.post(`${this.baseUrl}${url}`, data ) .map(this.parseData) .catch(this.handleError.bind(this)); } private parseData(res: Response) { return res.json() || []; } 

我认为这是您建议的与区域相关的问题。在这种情况下:

  onSubmit(request){ this.message="outer message" this.loginRequest = this.authService.login(request); this.loginRequest.subscribe((result) => { if(result.msg){ this.message ="inner message" // alert(this.message) } }); } 

当onSubmit()触发时,我看到“外部消息”绑定,但是进入订阅后它消失了,并且“内部消息”根本没有显示。

我发现了问题。 在我的AuthService中,在login()函数中返回一个Observable,我正在调用this.routeAfterLogin(false)。 如果发生错误,此功能会将我的路线重定向到登录页面。 可观察内部的重定向使更改检测变得混乱。 实际上,我不需要它,将其删除后一切都可以正常工作。 谢谢大家的帮助。

  public login(data): Observable<any> { return this.rHttp.post(ApiRoutes.LoginRoute,data).pipe(map(result=>{ if(...){ // not relevant }else{ let msg = "error message"; this.alertService.error(msg); **this.routeAfterLogin(false);** this.messageService.sendMessage('',Events.UserLogout); return {msg:msg}; } })); } **private routeAfterLogin(state:boolean)** { this.userIsLoggedIn = state; if(this.userIsLoggedIn){ this.router.navigate(['/home']); console.log("Login"); } else { this.router.navigate(['/login']); console.log("Failure Login"); } } 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM