【问题标题】:Angular 2 - Using Observables in a component to emit values to other componentsAngular 2 - 在组件中使用 Observables 向其他组件发出值
【发布时间】:2016-07-16 23:30:03
【问题描述】:

我想知道是否可以在组件中使用Observables,还有哪些其他组件可以订阅?

BugListComponent - 组件被注入到我加载所有服务的 boot.ts 文件中(boostrap 所在的位置)

import {Subject, BehaviorSubject} from 'rxjs/Rx';

viewBugList$: Subject<boolean>;

constructor() { 
    this.viewBugList$ = new BehaviorSubject<boolean>(false);
}

// Called from template, sends in 'true'
private enableIEview(enable: boolean) {   
    if(enable) {
        this.viewBugList$.next(true);
    }
}

BugListContainerComponent

import {BugListComponent} from '../buglist/bug-list.component';

initView: boolean;

constructor(private _bugListComp: BugListComponent) {
    this.initView = false;
}

ngOnInit() {
    this._bugListComp.viewBugList$.subscribe(e => {
        if(e != null) {
            this.initView = e;
        }
    });
}

所以,到目前为止,当从 BugListComponent 调用 .next 时,BugListContainerComponent 中的“订阅”似乎没有受到影响。

以下是概览图:

我错过了什么? 谢谢!

【问题讨论】:

    标签: asynchronous angular reactive-programming observable


    【解决方案1】:

    事实上这是不可能的。您只能使用定义为子组件的@OuputEventEmitter 类向组件的父组件触发事件。

    对于其他组件,您需要在共享服务中定义Observable。组件可以注入这个服务并订阅 observable。其他组件也可以注入服务并触发事件。

    这和你的代码几乎一样,但在服务服务中。

    • 共享服务

      export class SharedService {
        constructor() { 
          this.viewBugList$ = new BehaviorSubject<boolean>(false);
        }
      
        enableView() {
          this.viewBugList$.next(true);
        }
      }
      
    • 在引导时定义服务

      bootstrap(AppComponent, [ SharedService ]);
      
    • BugListContainerComponent

      constructor(private service: SharedService) {
        this.initView = false;
      }
      
      ngOnInit() {
        this.service.viewBugList$.subscribe(e => {
          if(e != null) {
            this.initView = e;
          }
        });
      }
      
    • BugListComponent

      viewBugList$: Subject<boolean>;
      
      constructor(private service:SharedService) { 
        this.viewBugList$ = new BehaviorSubject<boolean>(false);
      }
      
      // Called from template, sends in 'true'
      private enableIEview(enable: boolean) {   
        if(enable) {
          this.service.viewBugList$.next(true);
        }
      }
      

    必须在引导您的应用程序时定义此共享服务,以便为整个应用程序提供一个实例。

    【讨论】:

    • 啊哈,所以我害怕。所以可以通过 SidebarComp 将 @output 从 BugListComp 传递给 AppComp?然后@input 通过 MainContainerComp 从 AppCom 下到 BugListContainerComp?那么可能更容易为它创建一个服务^^谢谢你的快速回答顺便说一句!
    • 是的,这可能是可能的,但事件不会冒泡。因此,您需要在每个级别定义它们。所以这会很痛苦......是的,创建服务肯定更容易;-)
    • 好的,谢谢!对于这些类型的服务,它们将非常小并且只发出例如。真/假,如果会有几种类似的情况,在一项服务中收集这些是否可行?还是为他们每个人提供一项服务?
    • 是的,有道理。事实上,您可以随意组织它;-) 只有一项服务具有多个属性,多个属性,......这取决于您
    • 我有一个问题...角度 2 中的这个 shareService 就像 websocket?我的意思是活着?或者我们应该触发一个发送值的事件?我有一个想法......我想创建一个服务并观察一个属性,当更改为真或假时......发送值......这个 shareService 就像我的想法?!如何创建这样的服务?
    【解决方案2】:

    BugListComponent

    import 'rxjs/Rx';
    import {Output,EventEmitter} from 'angular2/core';
    import {sharedService} from './sharedService';
    
    
    constructor(private ss:sharedService) { 
    
    }
    
    private enableIEview(enable: boolean) {   
        if(enable) {
            this.ss.setEventEmitter(enable);
        }
    }
    

    sharedService.ts

    import 'rxjs/Rx';
    import {Output,EventEmitter} from 'angular2/core';
    
    export class sharedService {
    
    @Output() viewBugList$:EventEmitter<boolean>=new EventEmitter();
    
      constructor() { 
    
      }
    
      setEventEmitter(enable:boolean) {
        //this.viewBugList$.emit(enable);
          this.viewBugList$.next(enable);
      }
    
      getEventEmitter()
      {
         return this.viewBugList$;
      }
    }
    

    boot.ts

    import {sharedService} from './sharedService';
    bootstrap(AppComponent, [ SharedService ]);
    

    BugListContainerComponent

    import 'rxjs/Rx';
    import {Output,EventEmitter} from 'angular2/core';
    import {sharedService} from './sharedService';
    
    initView: boolean;
    
    constructor(private ss:shareService) {
        this.initView = false;
    }
    
    ngOnInit() {
        this.ss.getEventEmitter.subscribe(e => {
            if(e != null) {
                this.initView = e;
            }
        });
    }
    

    【讨论】:

      猜你喜欢
      • 2017-06-08
      • 1970-01-01
      • 2021-04-28
      • 2017-10-09
      • 1970-01-01
      • 2018-03-11
      • 1970-01-01
      • 1970-01-01
      • 2019-07-03
      相关资源
      最近更新 更多