Nativescript:Angular2 ListView在使用observable时不会更新

时间:2016-05-29 09:06:18

标签: angular nativescript

我有一个返回列表的外部API。我在服务中有以下内容

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

我在组件中有以下代码:

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

如果我取消注释上面的最后一行,则会在ListView上呈现。我的ListView被模板化了,如下所示:

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

API返回如下内容:

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

2 个答案:

答案 0 :(得分:2)

您可以在调用加载方法setTimeout(() => {this.cd.markForCheck();}, 0);后添加此行。这将允许每次将新项目推送到阵列时更新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();
            });
  }

答案 1 :(得分:1)

只是提示

使用map代替forEach()push()应该做同样但更简洁的事情:

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