【问题标题】:Angular multiple component share data by service not workingAngular 多组件通过服务共享数据不起作用
【发布时间】:2021-03-26 23:02:03
【问题描述】:

这是共享服务 (dShareService) =>

@Injectable()
export class DInfoShareService {
    constructor() { }

    // Observable sources    
    private dInfo = new Subject<DInfo>();

    dInfo$ = this.dInfo.asObservable();

    // Service message commands
  public SetDInfo(dinfo: DInfo) {     
    this.dInfo.next(dinfo);
  }
}

这是父母 =>

在父级,我有按钮单击事件并将数据传递给方法,值是传递给服务。

GoToDetail(value){       
    this.dShareService.SetDInfo(value);

    //this is child component and call by route, basically, I use this state and pass data to child 
    //component but this time, I have 3 tab page at UI and each page needs this data.
   
 this.router.navigateByUrl('/dchild', {
          state: {dInfo: value}
    });

这是子组件 =>

在构造函数中,

this.dinfoShareService.dInfo$.subscribe(res=>
     {
       //this one never happen
       this.dInfo = res;
     } 
  );

这个在子节点上的订阅永远不会被触发。我可以知道我错了吗?

【问题讨论】:

  • 使用 BehaviorSubject 代替
  • @enno.void 谢谢。我更改为 BehaviourSubject 并按预期工作。

标签: angular typescript angular-components


【解决方案1】:

您对服务中的主题的实现有误:

@Injectable()
export class DInfoShareService {
    constructor() { }

    // Observable sources    
    private dInfo = new Subject<DInfo>();


    // Service message commands
  public SetDInfo(dinfo: DInfo) {     
    this.dInfo.next(dinfo);
  }
}

它不应该在构造函数内部调用,在 ngOninit 内部使用它

     ngOnInit(): void {

this.dinfoShareService.dInfo.subscribe(res=>
     {
       //this one never happen
       this.dInfo = res;
     } 
  );


});

【讨论】:

    【解决方案2】:

    您需要将您的装饰器更改为 @Injectable({ providedIn: 'root' }) 以使其跨组件成为单例。否则它将为多个组件提供多个实例。

    还注意到:

    GoToDetail(value){       
        this.dShareService.SetDInfo(value);   
        this.router.navigateByUrl('/dchild', {
              state: {dInfo: value}
        });
    }
    

    上面的代码在导航之前调用了SetDInfo方法。所以你的子组件在值集之后订阅。您需要将您的Subject 更改为BehaviorSubject,以便您可以读取最后设置的值。

    【讨论】:

      【解决方案3】:

      试试这样, 服务.ts 文件

      import { BehaviorSubject, Observable, throwError } from 'rxjs';
      
      @Injectable({
        providedIn: 'root'
      })
      export class ApiWalletService {
        private behave = new BehaviorSubject<Object>('');
      
        setBehaviorView(behave: object) {
          this.behave.next(behave);
        }
      
        /** Get Behavior for user registraion */
        getBehaviorView(): Observable<object> {
          return this.behave.asObservable();
        }
      
      }
      

      component1.ts

       {
           ngOnInit() {
                  this.setBehaviorView({
                    'data':'XYZ'
                  })
             }
          }
      

      component2.ts

      {
      
       constructor(private service: Service){}
      
       ngOnInit() {
       this.service.getBehaviorView().subscribe(async (data) => {
         if (data && data != undefined) {
            console.log(data)
          }
        })
      }
      }
      

      【讨论】:

        猜你喜欢
        • 2019-03-05
        • 1970-01-01
        • 2017-10-16
        • 2017-04-15
        • 2017-08-27
        • 1970-01-01
        • 2018-05-22
        相关资源
        最近更新 更多