首页 文章

Angular 2服务RxJS BehaviorSubject或EventEmitter

提问于
浏览
2

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

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

我可以想到两个选择:

  • 为服务中的2个导航指令创建2个单独的Observables / BehaviorSubjects,让 Headers 将打开和关闭消息传递给它们,并让各个导航指令订阅每个相应的Observable .

  • 使用EventEmitters,但我不知道如何使用这种方法 .

能否请您提出解决此问题的好方法?

包含导航的自定义组件:

@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!';
}

Headers 组件:

@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

    由于您的组件松散耦合(彼此不了解)并且您需要在它们之间进行一些交互,因此您的方法(使用RxJS)是最相应的angular2方法 .

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

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

相关问题