Angular 4 UI not updating from observable subscription
我在我的应用程序组件中订阅的服务中有一个 observable。数据正在通过订阅传递,没有问题,但由于某种原因,我无法让 UI 使用新信息进行更新。我知道数据正在到达那里,因为它正在记录到控制台。
这是我的 app.component 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import {Component, OnDestroy, OnInit} from '@angular/core'; import {UserDetailsService} from './services/user-details.service'; import {User} from './shared/models/user'; import {Subscription} from 'rxjs/Subscription'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit, OnDestroy { title = 'the Portfolio'; user: User; userSub: Subscription; constructor(public userDetails: UserDetailsService) { } ngOnInit(): void { this.userSub = this.userDetails.user$.subscribe(user => { this.user = user; console.log(user); }); } ngOnDestroy() { this.userSub.unsubscribe(); } } |
我更新 observable 的用户登录组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | import {Component, AfterViewInit, NgZone} from '@angular/core'; import {UserDetailsService} from '../services/user-details.service'; import {User} from '../shared/models/user'; declare const gapi: any; @Component({ selector: 'app-user-login', templateUrl: './user-login.component.html', styleUrls: ['./user-login.component.css'] }) export class UserLoginComponent implements AfterViewInit { constructor(private _zone: NgZone, private userDetails: UserDetailsService) { console.log(this); } ngAfterViewInit() { gapi.load('auth2', () => { const auth = gapi.auth2.init({ 'clientId': 'YOURID.apps.googleusercontent.com' }); auth.attachClickHandler('google-login-button', {}, (googleUser) => { const profile = googleUser.getBasicProfile(); // console.log('Token || ' + googleUser.getAuthResponse().id_token); // console.log('ID: ' + profile.getId()); // console.log('Name: ' + profile.getName()); // console.log('Image URL: ' + profile.getImageUrl()); // console.log('Email: ' + profile.getEmail()); this.userDetails.setLoginUser(new User({ id: profile.getId(), name: profile.getName(), email: profile.getEmail() })); }, (error) => { alert(JSON.stringify(error, undefined, 2)); }); }); } } |
用户详情服务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import {Injectable, OnInit} from '@angular/core'; import {User} from '../shared/models/user'; import {BehaviorSubject} from 'rxjs/BehaviorSubject'; import 'rxjs/add/operator/map'; @Injectable() export class UserDetailsService implements OnInit { private userSubject = new BehaviorSubject<User>(new User()); user$ = this.userSubject.asObservable(); constructor() { } ngOnInit(): void { } public setLoginUser(user: User) { this.userSubject.next(user); } } |
这是我的 UI 代码:
1 2 | {{user.name}} {{user.name}} |
我错过了什么?已经坚持了一天多。
任何帮助表示赞赏,在此先感谢。
我不确定您是否需要运行该区域,因为在我的应用程序中类似的情况下我不需要。我在服务中使用 getter 和 setter 方法。你能在这里看看吗 https://github.com/JanneHarju/MultiSourcePlayList/blob/master/angular2App/app/services/playlist.service.ts
getPlaylistsModified() 函数。
发现问题。当我使用 setLoginUser 函数更新服务时,我这样做了:
1 2 3 4 5 | this.userDetails.setLoginUser(new User({ id: profile.getId(), name: profile.getName(), email: profile.getEmail() })); |
我需要这样做:
1 2 3 4 5 6 7 | this._zone.run(() =>{ this.userDetails.setLoginUser(new User({ id: profile.getId(), name: profile.getName(), email: profile.getEmail() })); }); |
现在这两种方法都起作用了:
1 2 | {{user.name}} {{(userDetails.user$ | async).name}} |
感谢你们的帮助!