2

我已經創建了一個組件:Angular2 + RxJS

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

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

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

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

    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')); //this.currentMonthObserver is undefined 
     }); 
    } 
} 

問題: 我得到:Cannot read property 'next' of undefinedthis.currentMonthObserver.next線(見張貼代碼的註釋)。

注:我按照這個博客教程,我是一個完全陌生的RxJS:https://coryrylan.com/blog/angular-2-observable-data-services

模板:

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

enter image description here

回答

4

此代碼this.currentMonthObserver = observer;

this.currentMonth$ = new Observable((observer: Observer<Moment>) => { 
    this.currentMonthObserver = observer; 
}).share(); 
只有當您訂閱 this.currentMonth時,纔會執行

。 因此this.currentMonthObservernull,因爲它沒有被初始化。

constructor() { 
    this.currentMonth$=new Subject().startWith(0).share(); 
} 

increment() { 
    this.currentMonth$.next(1); 
} 

decrement() { 
    this.currentMonth$.next(-1); 
} 
+0

你能指出一個方法來在我得到異常之前初始化它嗎?我在一個子組件中訂閱它。 – vlio20

+0

我不確定你的代碼是你真正想要完成的。爲了使這一步工作,你需要調用'this.currentMonth.subscribe();'。 –

+0

我在模板上有2個按鈕,應該將用戶界面移動到下一個和上一個月。請參閱模板(在更新的問題中) – vlio20

1

不知道究竟正在試圖做什麼,但假設你有按鈕,在視圖中公司和你的月月,我認爲你可以簡化不少:

export class MonthView { 
    currentMonth$: Observable<Moment>; 
    tickMonth$: new Subject<Number>(); 

    constructor() { 
    this.currentMonth$ = tickMonth$ 
     .scan((myMoment: Moment, tickMonthValue: number) => myMoment.clone().add(tickMonthValue, 'M')) 
     .startWith(new Moment()); 
    } 
} 

那麼在你看來,你可以做(click)="tickMonth$.next(1)"(click)="tickMonth$.next(-1)"分別增加和減少的月份

然後你只需使用currentMonth | async讓你一個月