如何在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);

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

为什么要将回调传递给服务,而不在组件的订阅中执行此功能?

类似这样的东西:

// 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(函数时,消息如上所示。。但是模板插值没有变化。

是。。这是一个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);
});
}
}

handleAuthentication((函数是从app.component..调用的

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() || [];
}

试试这个并告诉我。

  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);
}
}

正如您所建议的,我认为这是一个与区域相关的问题。。在这种情况下:

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中,在返回Observable的login((函数中,我正在调用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");
}
}

最新更新