2016-06-23 9 views
2

前の質問hereでは、2つのメッセージの間で変更された場合にのみ日付を表示しようとしています。Angular2:* ngFor、AsyncPipe、およびインデックス

違いは、私は今、リアルタイムデータベース(Firebase)に接続されていますということですので、私は、データ・ソースをサブスクライブし、指標と* ngIfを通過する前に、非同期パイプを通してそれを渡す:

<div *ngFor='let message of (chat | async) ; let i = index'> 
    <button *ngIf="i == 0 || (message.timestamp | date: 'ddMMMMyyyy') != ((chat | async)[i-1].timestamp | date: 'ddMMMMyyyy')"> 
     {{ message.timestamp | date:'ddMMM' }} 
    </button> 
    ... 
    <!--More html elements below (omitted)--> 
    ... 
</div> 

この私は最初のビューをロードする際によく働く私はchatに新しいエントリをプッシュする場合は、しかし、私は次のエラーを取得する:

TypeError: Cannot read property '0' of null

たぶん私はどのように非同期パイプ作品あまりわかりませんが、ときに私お試しください{{ (chat | async).length }}を返すと、意図したとおりに動作します。回避策/適切な練習に関する提案はありますか?

+0

あなたはチェックしましたか?バグかもしれない。 –

+0

@GünterZöchbauer短絡は、インデックス0のメッセージの前には何もないので、trueを返す必要があります。インデックス1で、 '[i-1]'は0と評価され、例外がスローされます。 – shinglesmingles

+0

私はそれが意図されていることを知っていますが、実際に起こっているかどうかは疑いがあります。 –

答えて

2

ここではAsyncPipeをどのように操作できるかわかりませんが、パイプを使用しないという回避策を見つけるためにはマージしました。うまくいけば、私はこれをマークする前に、より良い答えを待つだろう。

私のクラスのデータソースを購読し、それを表示する前にforループを使って配列を操作します。私の質問で

(テンプレート)のコードは、今となっています:

<div *ngFor='let message of messages; let i = index'> 
    <button *ngIf="message.isNewDay"> 
     {{ message.timestamp | date:'ddMMM' }} 
    </button> 
    ... 
    <!--More html elements below (omitted)--> 
    ... 
</div> 

とコントローラで:

private chatid: string //chat id passed from previous screen 
private chat: FirebaseListObservable<any>; 
private messages: any = []; 

constructor(private firebase: FirebaseService, 
      private _datepipe: DatePipe) { 
} 

ionViewLoaded() { 
    this.chat = this.firebase.database.list('/chat-messages/' + this.chatid); 
    this.chat.subscribe((data) => { 
     this.messages = data; 
     for (let i: number = 0; i < this.messages.length; i++) { 
      if (i === 0) 
        this.messages[i].isNewDay = true; 
      else { 
       let date1 = this._datepipe.transform(this.messages[i].timestamp, 'ddMMMMyyyy'); 
       let date2 = this._datepipe.transform(this.messages[i-1].timestamp, 'ddMMMMyyyy'); 
       if (date1 !== date2) 
        this.messages[i].isNewDay = true; 
       else 
        this.messages[i].isNewDay = false; 
      } 
     } 
    }); 
} 

は、私は現在、クラスコードにDatePipeを使用しています。注(だけでなく、テンプレート内ではproviders: [DatePipe]と一緒にpipes: [DatePipe]を使用する必要があります)。他の場合、誰かに

3

は、それがキーワードとの最初の結果だから、私は(messagesは、反復可能なの観察可能であると仮定して)、このような非同期パイプで* ngForのインデックスを取得することができた、これを見つけた:

<div *ngFor="let message of (messages | async); let i = index;"> 
0

日付を表示する(または表示しない)機能を使用します。だから、それが変化した場合にのみ(この例では)日付を表示する:showOnChangeで

<ion-list no-lines> 
<ion-item-sliding *ngFor="let trip of tripsExt$ | async; let i = index"> 
    <ion-item> 
    <ion-row (click)="change(trip)"> 
     <ion-col col-6> 
     {{showOnChange(trip.date)}} 
     </ion-col> 
     <ion-col col-6> 
     {{trip.end_address_name}} 
     </ion-col> 
    </ion-row> 
    </ion-item> 
    <ion-item-options side="left"> 
    <button ion-button color="primary" (click)="delete(trip)"> 
     Delete 
    </button> 
    </ion-item-options> 
</ion-item-sliding> 
</ion-list> 

を:テンプレートで使用された場合、 `||は`短絡であれば

showOnChange(currentDate) { 
    if (currentDate != this.previousDate) { 
     this.previousDate = currentDate 
     return currentDate 
    } 
    return '' 
    } 
関連する問題