angular2绑定不适用于谷歌oauth2承诺

时间:2016-07-20 00:19:03

标签: angular google-oauth2

一切都按预期工作但我无法让视图更新。

我希望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 - 谢谢

2 个答案:

答案 0 :(得分:1)

通过在订阅中添加另一个控制台日志来确认是否正在设置this.user。

console.log(this.user);

我认为它会被设置,但UI不是更新是你的问题。只是为了入门,您可以尝试在超时中包装用户集,并查看UI更新是否像

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

如果这让你工作,那么你设置变量太早/太晚,无法进行变化检测。

setTimeout不是理想的实现方法,所以我们应该以适当的方式重构代码,以确保angular2变化检测能够获得更改。如果这让你工作发布关于模板的更多细节或者提出了一个plunker,我们可以看到什么是更好的实现方式。

答案 1 :(得分:0)

问题见于此解释性代码段..

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出现此类问题。

值得知道这个在auth2.grantOfflineAccess

内的auth2.grantOfflineAccess === 这个之外