Angular 2服务+ RxJS BehaviorSubject或EventEmitter [英] Angular 2 Service + RxJS BehaviorSubject or EventEmitter

查看:84
本文介绍了Angular 2服务+ RxJS BehaviorSubject或EventEmitter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am new to Angular 2 and RXJS. I have a custom header component with 2 triggers (buttons) which should activate 2 different navigation directives in different parts of the application. I have created a service which registers the 2 different navigation directives and the header component subscribes to this. I wanted to know whats the best way to link the buttons in the header to call the open() and close() functions in each of the directives depending on the trigger that is clicked.

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

NOTE: Please note that I cannot use ViewChild or ContentChild because the navigation can be anywhere on the page. They can be in a different CustomComponent and are not necessarily children of the header component.

我可以想到2种选择:

  1. 为Service中的2个导航指令创建2个单独的Observables/BehaviorSubjects,并让标头将打开和关闭消息传递给它们,并使各个导航指令分别订阅这些对应的Observables.
  2. 使用EventEmitters,但我不确定如何使用此方法.

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

Could you please suggest a good way to solve this?

包含导航的自定义组件:

Custom Component containing the Navigation:

@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:

NavService:

@Injectable()
export class NavService {
  public _navSubject: BehaviodSubject = new BehaviorSubject<number>(0);

  registerNavId(id: number) {
    this._navSubject.next(id);
  }
}

Nav1Directive

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:

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");
  }
}

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

推荐答案

由于您的组件之间是松散耦合的(彼此不了解),并且您需要它们之间的某种交互,因此您的方法(使用RxJS)是最合适的接近angular2.

Since your components are loosely coupled (don't know each other) and you need some interaction between them, your approach (to use RxJS) is the most corresponding approach to angular2.

现在一切都变得反应灵敏,甚至是表格​​.

Everything goes Reactive now, even Forms.

当您具有来自可重用组件的输出事件时,EventEmitter既好又简单.

EventEmitter is good, and simple, when you have output events from reusable components.

这篇关于Angular 2服务+ RxJS BehaviorSubject或EventEmitter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆