2016-05-29 14 views
0

リストを返す外部APIがあります。私はその上の最後の行がListView上でレンダリングされたコメントを解除する場合はNativescript:Angular2 Observableを使用中にリストビューが更新されない

ngOnInit() { 
    this._groceryService.load() 
     .subscribe(loadedGroceries => { 
      loadedGroceries.forEach((groceryObject) => { 
       console.dir(groceryObject); 
       this.groceryItems.unshift(groceryObject); 
      }); 
     }); 

    // It works if I uncomment this. It will just render one item, still nothing from API 
    // this.groceryItems.unshift(new Grocery('iuiu', 'jjjjj')); 
} 

:私は、コンポーネントに次のコードを持っているサービス

load() { 
    let headers = new Headers(); 
    headers.append("Authorization", Config.token); 

    return this._http.get(Config.apiUrl + "grocery/list", {headers: headers}) 
     .map(res => res.json()) 
     .map(data => { 
      let groceryList = []; 
      data.list.forEach((grocery) => { 
       groceryList.push(new Grocery(grocery._id, grocery.name)); 
      }); 
      return groceryList; 
     }) 
     .catch(this.handleErrors); 
} 

を次のようしています。私ListViewは離れテンプレートと以下のように見えるさ:

<GridLayout> 
    <ListView [items]="groceryItems" class="small-spacing"> 
    <template let-item="item"> 
     <Label [text]="item.name" class="medium-spacing"></Label> 
    </template> 
    </ListView> 
</GridLayout> 

APIは、このようなものを返す:あなたはloadメソッドsetTimeout(() => {this.cd.markForCheck();}, 0);を呼び出した後

{ 
    "success": true, 
    "msg": "Lists found!", 
    "list": [ 
    { 
     "_id": "574a324a18cadad00665a7f3", 
     "name": "Carrot", 
     "userid": "57482f309ae6c358703066ca", 
     "completed": 0, 
     "__v": 0 
    } 
    ] 
} 
+1

ちょっとDeepak、私は具体的には何がわからないここで間違っているのですが、私もこの種の問題にぶつかりました。非同期パイプと同様に、リストのRxJS Observableに切り替えることを検討することをお勧めします。それはちょうどAngularがこの種のものを実装するのを望んでいるようですが、私はそのアプローチでより良い運を得ました。 Groceriesレポの「角張った」ブランチには、サンプル実装があります。https://github.com/NativeScript/sample-Groceries/tree/angularをご覧ください。 –

答えて

1

代わりforEach()push()mapを使用するだけで、ヒント

は同じですが、より簡潔な操作を行う必要があります。

load() { 
    let headers = new Headers(); 
    headers.append("Authorization", Config.token); 

    return this._http.get(Config.apiUrl + "grocery/list", {headers: headers}) 
     .map(res => res.json()) 
     .map(data => 
      data.list.map(grocery => new Grocery(grocery._id, grocery.name)) 
     ) 
     .catch(this.handleErrors); 
} 
2

あなたはこの行を追加することができます。これにより、新しい項目を配列にプッシュするたびにListViewが更新されます。私はいくつかのコードスニペットの下に取り付けています:

import {Component, Input, ChangeDetectionStrategy, ChangeDetectorRef} from "@angular/core"; import {Http, Headers, Response, ResponseOptions, HTTP_PROVIDERS} from "@angular/http"; import {Observable, BehaviorSubject} from "rxjs/Rx";

constructor(private _http: Http, private cd: ChangeDetectorRef){ 

     this.groceryItems=[]; 
    } 



ngOnInit() { 
     this.groceryItems.push(new Grocery('3','test', false, false)); 
     this.load() 
      .subscribe(loadedGroceries => { 
       loadedGroceries.forEach((groceryObject) => { 
        this.groceryItems.push(new Grocery('3',groceryObject.name, false, false)); 
        console.log(this.groceryItems.length); 
        console.log(groceryObject.name); 
       }); 
       this.cd.markForCheck(); 
      }); 
    } 
+0

'cd.markForCheck()'の呼び出しに 'setTimeout()'が必要だと思いますか? –

+0

'this.cd.markForCheck()'は既に変更について通知する必要があります。 'setTimeout()'自体も変更について通知します。これは冗長で、特にデフォルトの 'ChangeDetectionStrategy'のようです。 –

+0

あなたは正しいです。プロジェクトのテストをもう一度行い、 'this.cd.markForCheck()'が 'setTimeout()'なしで正しく動作するように見えます。 –

関連する問題