Angular2 - 父母和孩子通过服务进行交流

Posted

技术标签:

【中文标题】Angular2 - 父母和孩子通过服务进行交流【英文标题】:Angular2 - Parent and children communicate via a service 【发布时间】:2017-07-20 21:51:11 【问题描述】:

我正在尝试在子组件之间进行通信,但是根据文档,我需要为每个服务执行此操作,并且在检索服务信息时遇到困难,当我尝试分配订阅返回时,如果我给出console.log(),它可以工作,现在如果我分配给一个变量,它不会配置它之后访问它,给出 undefined 作为答案。

将信息传递给另一个子类

import  Component, OnInit  from '@angular/core';
import Angular2TokenService, ResetPasswordData  from 'angular2-token';
import  ActivatedRoute, Router, Params  from '@angular/router';
import  AuthService  from '../services/auth.service';


@Component(
selector: 'app-forgot-passoword',
templateUrl: './forgot-passoword.component.html',
styleUrls: ['./forgot-passoword.component.scss']
)
export class ForgotPassowordComponent implements OnInit 
_resetPasswordData: ResetPasswordData = <ResetPasswordData>;
tenancy:string;
error:string;
private _sub:any;

constructor(
  private _tokenService: Angular2TokenService,
  private _route: ActivatedRoute,
  private _router: Router,
  private _authService: AuthService
) 


ngOnInit() 
  this._sub = this._route.parent.params.subscribe(
  params=> this.tenancy = params['tenancy']
  )


onSubmit(event)
  event.preventDefault();
  this.error = '';
  this._tokenService.resetPassword(
    email: this._resetPasswordData.email,
  ).subscribe(
    res => 
      console.log(this.tenancy);
      this._authService.confirmResetPassword("check your email");
      this._router.navigate([this.tenancy,'signin'])
   ,
    error => this.error = "Error aconteceu algo"
  );

  


服务。

  import  Injectable  from '@angular/core';
  import  ActivatedRoute  from '@angular/router';
  import  Location  from '@angular/common';
  import  Angular2TokenService  from 'angular2-token';
  import  environment  from './../../../environments/environment';
  import  Subject  from 'rxjs/Subject'

  @Injectable()
  export class AuthService 
    tenancy: string;
    private resetPasswordConfirmed = new Subject<string>();
    passwordConfirmed$ = this.resetPasswordConfirmed.asObservable();

    constructor(private _tokenService: Angular2TokenService,
      private activateRoute: ActivatedRoute,
      private _location: Location)  

    init()
      this.tenancy = this._location.path().split('/')[1];
      let apiBase:string; 
      if(environment.name==='mock')
        apiBase = `http://$environment.apiEndPoint`;
       else 
        apiBase = `http://$this.tenancy.$environment.apiEndPoint`;
      
      this._tokenService.init(
        apiBase: apiBase
      );
    

    confirmResetPassword(mensagem: string) 
      this.resetPasswordConfirmed.next(mensagem);
    
  

以及将使用服务数据的其他类;

      import  ActivatedRoute, Router  from '@angular/router';
      import  Angular2TokenService, SignInData  from 'angular2-token';
      import  Component, OnInit  from '@angular/core';
      import  AuthService  from '../services/auth.service';
      import  Subscription  from 'rxjs/Subscription'


      @Component(
        selector: 'app-signin',
        templateUrl: './signin.component.html',
        styleUrls: ['./signin.component.scss']
      )
      export class SigninComponent implements OnInit 
        private _signInData: SignInData = <SignInData>;
        tenancy:string;
        error:string;
        resetPasswordSucess:string;
        _sub: any;
        subscription: Subscription;

        constructor(
          private _tokenService: Angular2TokenService,
          private _route: ActivatedRoute,
          private _router: Router,
          private _authService: AuthService
        )   
          this.subscription= _authService.passwordConfirmed$.subscribe(
              mensagem => 
                this.resetPasswordSucess = mensagem;
                console.log(mensagem + '  Mensagem');
                    
            ); 

        
        ngOnInit() 
          this._sub = this._route.parent.params.subscribe(
            params=> this.tenancy = params['tenancy']
          );
        

        onSubmit()

          this.error = '';
          this._tokenService.signIn(this._signInData)
            .subscribe(
              res   => console.log("DEU CERTO"),
              error => console.log(error)
            );

        
      

如果在订阅之外执行console.log(this.resetPasswordSucess),则变量值为UNDEFINED。

如何在变量中赋值,让订阅外的人都能看到?

【问题讨论】:

【参考方案1】:

resetPasswordSucess 属性只有在 passwordConfirmed$ 首次输出后才会设置

【讨论】:

【参考方案2】:

很可能当你的 ForgotPasswordComponent 调用时

this._authService.confirmResetPassword("check your email");

您的 SignInComponent 尚未订阅您服务中的 _authService.passwordConfirmed$

不要在 AuthService 中使用 private resetPasswordConfirmed = new Subject&lt;string&gt;();,而是尝试使用 private resetPasswordConfirmed = new BehaviorSubject&lt;string&gt;('');private resetPasswordConfirmed = new ReplaySubject&lt;string&gt;();

不同的是Subject 是火了就忘了。如果订阅者在触发时还没有订阅 observable,那么它就会错过这个值。当新订阅者订阅时,ReplaySubject 将重播过去的值。同样,BehaviorSubject 将在订阅时提供最新值,即使尚未收到下一个值。

来自http://reactivex.io/documentation/subject.html

行为主题: 当观察者订阅 BehaviorSubject 时,它首先发出源 Observable 最近发出的项目(如果还没有发出种子/默认值),然后继续发出源 Observable 稍后发出的任何其他项目( s)。

重播主题: 向任何观察者发出源 Observable 发出的所有项目,无论观察者何时订阅。

希望对您有所帮助。

【讨论】:

以上是关于Angular2 - 父母和孩子通过服务进行交流的主要内容,如果未能解决你的问题,请参考以下文章

NLP亲子关系助您成为“智慧父母”

Angular 2~6:与“组件”通信的最有效方式是啥?

如何从孩子的父母访问模板引用变量?

如何与人交流——程序员,赶紧生个孩子吧!

C(Linux)中的管道问题

在 AngularJS 组件中从父级到子级通信事件