【问题标题】:Angular2 - 'watch' provider property in multiple componentsAngular2 - 多个组件中的“监视”提供程序属性
【发布时间】:2016-04-07 21:07:29
【问题描述】:

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

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

我尝试了什么:

@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 中的新人。感谢您的努力。

【问题讨论】:

  • 所以你的onUserChangedAuth.login() 被调用后不会被调用?我重建了您示例的简单版本(在 Dart 中,没有路由和本地存储),它工作正常。
  • 没错!我正在分析@thierry templier 响应,我的代码与他相同,但 onUserChanged 中仍然没有警报。当我调试 NavComponent 时,订阅仅在构造函数初始化时触发。
  • 不确定我是否理解您的最后评论。难道你的NavComponent 是在事件触发后才创建的?
  • 我认为我们需要看到一个可以复制的运行示例。
  • “订阅仅在构造函数初始化时触发”是什么意思?您是否收到userUpdated 登录事件?

标签: angular observable eventemitter


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    您会注意到 Angular 中没有监视功能,因为它现在由区域管理。

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

    @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('/');
      }
    }
    

    希望对你有帮助 蒂埃里

    【讨论】:

    • 好的,但这是服务的属性而不是组件的属性。组件如何知道服务的字段已更改?
    • 事实上,Angular2 中没有$watch 支持,因为没有范围的概念。其他组件需要订阅userChanged 事件。我以这种方式更新了我的答案。
    • 您也可以在发送authorized事件时提供用户而不是true....
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-01
    • 2016-12-06
    • 2019-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多