Angular2 Observables最佳实践

时间:2016-03-05 19:33:32

标签: javascript angular rxjs

假设我有一个包含子组件的组件。例如这个简单的日历: enter image description here

这是它的模板:

<month-board [current-month]="currentMonth$"></month-board>
<button (click)="decrement()">Prev</button>
<button (click)="increment()">Next</button>

单击按钮时,订阅month-board订阅的currentMonth$正在更改显示的月份。

currentMonth$类型为Observable<Moment>。 我的问题是:将Observable传递给Angular2中的子组件是一种好习惯吗?有没有更好的方法呢?

父母完整代码:

@Component({
  selector: 'month-view',
  templateUrl: 'app/components/month-view/month-view.html',
  styleUrls: ['app/components/month-view/month-view.css'],
  directives: [MonthBoard],
})

export class MonthView {
  currentMonth: Moment = moment();
  currentMonth$: Observable<Moment>;
  currentMonthObserver: Observer<Moment>;
  decrement: Function;
  increment: Function;

  constructor() {
    this.currentMonth$ = Observable.create((observer: Observer<Moment>) => {
      this.currentMonthObserver = observer;
    });


    const decrementCounter$: Observable<Function> = Observable.create((observer) => {
      this.decrement = () => {
        observer.next();
      };
    });

    const incrementCounter$: Observable<Function> = Observable.create((observer) => {
      this.increment = () => {
        observer.next();
      };
    });

    this.currentMonth$.subscribe();

    Observable
      .merge(
        decrementCounter$.map(() => - 1),
        incrementCounter$.map(() => + 1)
      )
      .startWith(0)
      .scan((currentCount: number, value: number) => currentCount + value)
      .subscribe((count: number) => {
        this.currentMonthObserver.next(this.currentMonth.clone().add(count, 'M'));
      });
  }
}

儿童完整代码:

@Component({
  selector: 'month-board',
  templateUrl: 'app/components/month-board/month-board.html',
  styleUrls: ['app/components/month-board/month-board.css'],
  directives: [DayCell]
})
export class MonthBoard implements OnInit{
  @Input('current-month') currentMonth: Observable<Moment>;
  weeks: Moment[][];

  constructor(private calendarHelper: CalendarHelper) {
    this.weeks = this.calendarHelper.getMonthWeeks();
  }

  ngOnInit() {
    this.currentMonth.subscribe((month: Moment) => {
      this.weeks = this.calendarHelper.getMonthWeeks(month);
    });
  }
}

1 个答案:

答案 0 :(得分:1)

你可以这样做,另一种方式是使用@input。使用它将值从父级传递给子级非常容易。

https://angular.io/docs/ts/latest/api/core/Input-var.html

我认为将observable传递给你的子组件并不一定是坏事。例如,我有一个服务,它使用我的整个应用程序用来监视登录事件的observable。但是对于日历,您可能会发现自己想要在同一个observable的不同位置传递不同的值。如果你这样做,你总是可以做另一个观察。或者以不同的方式为每个组件操纵它。

但为了便于阅读,我肯定会使用@input,这样我只需要去父组件来弄清楚我要传递的内容。