Angular 2 Service + RxJS BehaviorSubject或EventEmitter

时间:2016-09-25 04:35:14

标签: angular rxjs

我是Angular 2和RXJS的新手。我有一个带有2个触发器(按钮)的自定义标头组件,它应该在应用程序的不同部分激活2个不同的导航指令。我已经创建了一个服务,它注册了2个不同的导航指令,并且标头组件订阅了这个。我想知道最新的方法是链接标题中的按钮,以根据单击的触发器调用每个指令中的open()和close()函数。

注意:请注意我无法使用ViewChild或ContentChild,因为导航可以在页面的任何位置。它们可以位于不同的CustomComponent中,也不一定是标题组件的子项。

我可以想到两个选项:

  1. 为服务中的2个导航指令创建2个单独的Observables / BehaviorSubjects,让标题传递打开和关闭消息,并让各个导航指令订阅每个相应的Observable。
  2. 使用EventEmitters,但我不知道如何使用此方法。
  3. 您能否建议一个解决此问题的好方法?

    包含导航的自定义组件:

    @Component({
      selector: 'my-app',
    
      template: `
        <h1>{{title}}</h1>
        <my-custom-header>
          This is some text inside the header
        </my-custom-header>
        <nav custom-nav-1>Custom Nav 1</nav>
        <nav custom-nav-2>Custom Nav 2</nav>
      `
    })
    export class AppComponent {
      title = 'Hello!';
    }
    

    标题组件:

    @Component({
      selector: 'my-custom-header',
    
      template: `
        <div class="container">
          This is a header
          <ng-content></ng-content>
          <div>Number of Nav Registered: {{noOfNav}}</div>
          <button type="button" (click)="toggleNav1()">Toggle Nav 1</button>
          <button type="button" (click)="toggleNav2()">Toggle Nav 2</button>
        </div>
      `,
      styles: ['.container { border: 1px solid; }'],
    })
    export class HeaderComponent {
      title = 'Hello!';
      noOfNav = 0;
    
      constructor(private navService: NavService) {}
    
      ngOnInit() {
        this.navService._navSubject.subscribe({
          next: (id) => {
            if(id!=0) {
              this.noOfNav++;
            }
          }
        });
      }
    
      toggleNav1() {
        console.log("Toggle Nav 1");
      }
    
      toggleNav2() {
        console.log("Toggle Nav 2");
      }
    }
    

    NavService:

    @Injectable()
    export class NavService {
      public _navSubject: BehaviodSubject = new BehaviorSubject<number>(0);
    
      registerNavId(id: number) {
        this._navSubject.next(id);
      }
    }
    

    Nav1Directive

    @Directive({
      selector: '[custom-nav-1]'
    })
    export class NavDirective1 {
      constructor(private navService: NavService) {}
    
      ngOnInit() {
        this.navService.registerNavId(1);
      }
    
      isOpen() {
        console.log("isOpen");
      }
    
      open() {
        console.log("Open Nav");
      }
    
      close() {
        console.log("Close Nav");
      }
    }
    

    Nav2Directive:

    @Directive({
      selector: '[custom-nav-2]'
    })
    export class NavDirective2 {
      constructor(private navService: NavService) {}
    
      ngOnInit() {
        this.navService.registerNavId(2);
      }
    
      isOpen() {
        console.log("isOpen");
      }
    
      open() {
        console.log("Open Nav 2");
      }
    
      close() {
        console.log("Close Nav 2");
      }
    }
    

    Plunker:https://plnkr.co/edit/3ISyH7ESoNlt65J56Yni?p=preview

1 个答案:

答案 0 :(得分:0)

由于你的组件松散耦合(彼此不了解)并且你需要它们之间的某些交互,你的方法(使用RxJS)是最相应的angular2方法。

现在一切都变得活跃,甚至形式。

当您从可重用组件输出事件时,EventEmitter很好,很简单。