angular2 绑定不适用于 google oauth2 promise

angular2 binding not working with google oauth2 promise

一切正常,但我无法更新视图。

我希望 ngOnInit() 中的订阅在每次数据流下来时更新视图。

但是,当数据顺流而下时,代码 this.user = user 不会更新视图 :(

我的组件代码是...

import {Component, OnInit} from '@angular/core';
import {Subject, Observable} from 'rxjs/Rx';
import {AuthService} from '../../../services/auth.service';
import 'rxjs/add/operator/catch';
declare let auth2:any;

@Component({
  selector: 'user',
  templateUrl: 'build/routes/app/user/user.component.html',
  styleUrls: ['build/routes/app/user/user.component.css'],
  providers: [AuthService]
})

export class UserComponent implements OnInit {

  private userSubject = new Subject<string>();
  public user:any;

  public userStream:Observable<any> = this.userSubject.asObservable().flatMap((code:any) => {
    let restStream = this.authService.signIn(code)
      .map((response:any) => {
        return JSON.parse(response._body);
      }).catch((err:any) => {
        return Observable.throw(err);
      });
    return restStream;
  }).publish().refCount();

  constructor(public authService:AuthService) {
  }

  ngOnInit() {
    this.userStream.subscribe((user:any) => {
      console.log(user); // user is set
      this.user = user; // this does not update the view :(
    });
  }

  public googleSignIn() {
    auth2.grantOfflineAccess({'redirect_uri': 'postmessage'}).then((authResult:any) => {
      this.userSubject.next(authResult.code);
    });
  }

}

视图简直...

<button (click)="googleSignIn()">Google Sign In</button>
<div>USER = {{user | json}}</div>

如何让 Angular2 更新视图?

注意:全局声明 auth2 指的是全局 Google OAuth2 - 谢谢

通过添加另一个控制台登录订阅来确认是否设置了 this.user。

console.log(this.user);

我认为它会被设置,但 UI 没有更新是你的问题。对于初学者,您可以尝试将用户设置包装在超时中并查看 UI 是否更新为

setTimeout( user => this.user = user, 0);

如果这能让您工作,那么您也可以设置变量 early/too 更改检测迟到了。

setTimeout 不是实现此目的的理想方法,因此我们应该以适当的方式重构您的代码,以确保 angular2 更改检测能够识别更改。如果这让您工作 post 有关模板的更多详细信息或提出一个 plunker,我们可以看到更好的实现方式。

在这个解释性代码片段中看到了问题..

public googleSignIn() {
  this.user = {fred:5}; // BINDINGS UPDATE HERE
  auth2.grantOfflineAccess({'redirect_uri': 'postmessage'}).then((authResult:any) => {
    this.user = {fred:6}; // BINDINGS DO NOT UPDATE HERE
    this.userSubject.next(authResult.code);
  });
}

任何尝试更新 auth2.grantOfflineAccess 内的数据或由此产生的任何函数或流都无法更新视图!

我终于使用 JavaScript 个事件解决了这个问题。

这里的主要区别是在this.userStream.subscribe内部调度了一个事件并且事件侦听器设置了this.user

这是我最终的工作解决方案..

import {Component, OnInit} from '@angular/core';
import {Subject, Observable} from 'rxjs/Rx';
import {AuthService} from '../../../services/auth.service';
import 'rxjs/add/operator/catch';
declare let auth2:any;

@Component({
  selector: 'user',
  templateUrl: 'build/routes/app/user/user.component.html',
  styleUrls: ['build/routes/app/user/user.component.css'],
  providers: [AuthService]
})

export class UserComponent implements OnInit {

  public user:any;

  private userSubject = new Subject<string>();
  public userStream:Observable<any> = this.userSubject.asObservable().flatMap((code:any) => {
    let restStream = this.authService.signIn(code)
      .map((response:any) => {
        return JSON.parse(response._body);
      }).catch((err:any) => {
        return Observable.throw(err);
      });
    return restStream;
  }).publish().refCount();

  constructor(public authService:AuthService) {
  }

  ngOnInit() {
    this.addUserEventListener();
    this.subscribeToUserStream();
  }

  public googleSignIn() {
    auth2.grantOfflineAccess({'redirect_uri': 'postmessage'}).then((authResult:any) => {
      this.userSubject.next(authResult.code);
    });
  }

  private addUserEventListener() {
    document.addEventListener('userEvent', (e:CustomEvent) => {
      this.user = e.detail;
    });
  }

  private subscribeToUserStream() {
    this.userStream.subscribe((user:any) => {
      let userEvent = new CustomEvent('userEvent', {'detail': user});
      document.dispatchEvent(userEvent);
    });
  }

}

这个解决方案有效,但我不知道为什么 auth2.grantOfflineAccess 在 Angular2 中会导致此类问题。

值得知道 this 外面 auth2.grantOfflineAccess === this 里面 auth2.grantOfflineAccess