Angular2 - ' watch'多个组件中的provider属性

时间:2016-01-04 09:27:19

标签: angular observable eventemitter

我来自NG1环境,目前我正在创建具有所有可用功能的NG2应用程序。在询问之前我正在探索谷歌和stackoverflow问题,但没有运气,因为角度2移动得如此之快,api架构和大多数答案都已过时。

我的情况: 我有属性用户的Auth提供者(服务),我想观察用户并在多个组件(导航栏,侧边栏等)中做出反应。

我尝试了什么:

@Injectable();
export class Auth {

    private user;
    authorized: EventEmitter<boolean>;

    constructor(public router:Router){
        this.authorized = new EventEmitter<boolean>();
    }

    login(user, token):void{
        localStorage.setItem('jwt', token);
        this.user = _.assign(user);

        this.authorized.emit(<boolean>true);
        this.router.parent.navigateByUrl('/');
    }
}


/***************/
@Component({...})
export class NavComponent {

     public isAuthroized: boolean = false;

     constructor(Auth:Auth){
         Auth.authorized
             .subscribe((data) => this.onUserChanged(data));
     }

     onUserChanged(user){
        alert('USER:' + user.email);
        this.isAuthroized = true;
     }
}

/****************/
bootstrap(AppComponent, [
     ROUTER_PROVIDERS,
     ELEMENT_PROBE_PROVIDERS,
     HTTP_PROVIDERS,
     MapLoader,
     Auth
])

但没有运气。我应该使用Observable EventEmitter还是有其他正确的方法来处理这种情况?在NG1中,它就像在服务的属性上设置$ watch一样简单。谢谢!

编辑: 我为Auth服务添加了新方法:

...
userUpdated: EventEmitter<boolean>;

constructor(public router:Router){
    this.userUpdated = new EventEmitter<any>();
}

...

logout(returnUrl?: string): void{
    delete this.user;
    localStorage.removeItem('jwt');
    this.userUpdated.emit(undefined);

    if(!_.isEmpty(returnUrl)){
        this.router.parent.navigateByUrl(returnUrl);
    }

}

现在调用事件,为什么这适用于注销而不是登录?

编辑2:

export class LoginPageComponent {
   error: string;

   constructor(public http: Http, public router: Router, public Auth:Auth){
   }

   login(event, email, password){
      ...
      this.http.post('/api/login', loginModel, {headers: headers})
        .map((res) => res.json())
        .subscribe((res: any) => {
            this.Auth.login(res.user, res.ADM_TOKEN);
        }, (error) => this.error = error._body);
   }

}

分辨

愚蠢的错误..我离开了提供者数组[Auth]中的NavComponent ..因此它与全局Auth不同的对象..抱歉伙计们!希望这个问题能帮助Angular2中的新人。谢谢你的努力。

2 个答案:

答案 0 :(得分:1)

我假设您要为每个组件添加Auth作为提供程序。这将为每个组件创建一个新的类实例。 仅在bootstrap(AppComponent, providers: [...])或仅在AppComponent上添加。

答案 1 :(得分:1)

您可以注意到Angular中没有手表功能,因为它现在由Zones管理。

要通知其他组件,您可以在EventEmitter服务中为Auth活动添加另一个userUpdated。想要通知的组件可以在此发射器上注册。

@Injectable();
export class Auth {
  private user;
  authorized: EventEmitter<boolean>;
  userUpdated: EventEmitter<boolean>;

  constructor(public router:Router){
    this.authorized = new EventEmitter<boolean>();
    this.userUpdated = new EventEmitter<boolean>();
  }

  login(user, token):void{
    localStorage.setItem('jwt', token);
    this.user = _.assign(user);

    this.authorized.emit(<boolean>true);
    this.userUpdated.emit(this.user);
    this.router.parent.navigateByUrl('/');
  }
}

组件可以注册此事件:

@Component({...})
export class NavComponent {
  (...)
  constructor(Auth:Auth){
    Auth.userUpdated
         .subscribe((data) => this.onUserChanged(data));
  }
}

您还可以在发出authorized事件时提供用户:

  login(user, token):void{
    localStorage.setItem('jwt', token);
    this.user = _.assign(user);

    this.authorized.emit(this.user);
    this.router.parent.navigateByUrl('/');
  }
}

希望它可以帮到你, 亨利