Angular2 ngFor:我做错了什么?

5

我在克服Angular2中似乎非常普遍的“无法找到支持对象'[object Object]'类型为'object'”错误时遇到了困难,希望有人遇到了类似的问题。

以下是来自我的服务的(匿名化的)JSON数据,非常简单:

[
    {
        "item_id": 1,
        "item_type": 2,
        "item_name": "Item 1",
        "item_description": "First item"
    },
    {
        "item_id": 2,
        "item_type": 4,
        "item_name": "Item 2",
        "item_description": "Second item"
    }
]

下面是我定义这些对象的类、服务和组件的内容:

// item.ts
export class Item {
    item_id: number;
    item_type: number;
    item_name: string;
    item_description: string;
}

//item.service.ts snippet
getItems(): Promise<Item[]> {
    return this.http.get('http://apiurl', { withCredentials: true })
    .toPromise()
    .then((response) => {
        let body = response.json();
        return body as Item[];
    })
    .catch(this.handleError);
}

//item.component.ts snippet
items: Item[];

getItems(): void { // Function that calls the item service
    this.itemService
    .getItems()
    .then((items) => {
        console.log(items); // I use this to verify that I'm getting an array.
        this.items = items;
    });
}

最后,是 ngFor 组件:

<ul>
    <li *ngFor="let item of items">
        <i class="fa fa-database"></i> {{item.item_name}}
    </li>
</ul>

我没有发现任何问题。 检索到的数据确实到达了项目组件,这意味着我的导入是正确的,并且在我的console.log中显示的内容绝对是一个数组,带有__proto__:Array[0]属性和其他所有属性。 它甚至看起来与Console log Angular教程Heroes应用程序输出的内容完全相同。 但是它仅仅不能迭代数组,坚持认为它是一个对象。
我做错了什么? ngFor只是坏了吗?
编辑 以下是完整的(匿名)类,已删除不相关的部分:
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Headers, Response, Http, RequestOptions } from '@angular/http';
import { Item } from '../../classes/item/item';
import { ItemService } from '../../services/item/item.service';

@Component({
    moduleId: module.id,
    selector: 'my-items',
    templateUrl: 'items.component.html'
})
export class ItemComponent implements OnInit {
    items: Item[] = [];

    constructor(
    private router: Router,
    private itemService: ItemService
    ) { }

    getItems(): void {
        console.log(this.items);
        this.itemService
        .getItems()
        .then((items) => {
            console.log(items);
            this.items = Array.from(items);
        });
    }

    ngOnInit() {
        this.getItems();
    }
}

编辑2:

我明白了!我认为这可能是Angular2中的一个错误。上面,我通过使用通用变量名“items”来对代码进行了净化。但在真正的生产代码中,变量被称为“entities”。而且一直以来,我都是用这个名字命名的。突发奇想,我把变量的名称改成了“testentities”,它就起作用了!

所以,为了确保,我测试了多种变化,每次都可以工作。然后我又把它改回了“entities”,错误又出现了。它似乎是某种保留变量。

我将严格测试这个问题,如果可以稳定地重现,我将在错误跟踪器上报告它。


语法看起来没问题,所以这一定是个打字错误或者其他什么问题,因为我没有看到任何发布的问题。确保所有变量和对象属性都拼写正确。还有这个 https://github.com/angular/angular/issues/6392 和这个 http://stackoverflow.com/questions/36401069/cannot-find-a-differ-supporting-object-error-angular2 - Logan H
@Sasquatch3o3,我已经仔细检查过变量名称,它们都没问题。如果我将ngFor模板注释掉,该组件就可以在没有任何错误的情况下加载了。 - Damon Kaswell
哦,刚刚发现了一些可能有用的东西。如果我在组件中注释掉this.items = items这一行(将Item[]数组留空),ngFor仍然会抛出错误。所以它将items: Item[]视为对象而不是数组。有什么想法吗? - Damon Kaswell
好的,很酷,让我再看一遍。 - Logan H
@cartant 现实生活阻止了我今天花更多的时间,但当我有时间时,我保证会把错误报告提交上来。 - Damon Kaswell
显示剩余4条评论
1个回答

1

请尝试一下

item.service.ts 片段

getItems(): Promise<Item[]> {
    return this.http.get('http://apiurl', { withCredentials: true })
    .toPromise()
    .then((response) => {
        let body = response.json();
        return body;
    })
    .catch(this.handleError);
}

item.component.ts 代码片段

items: Item[] = []; // For whatever reason it thinks this is an Object

getItems(): void { // Function that calls the item service
    //this.items = Array.from(this.items);
    this.itemService.getItems().then(items => this.items = items);
}

[更新]

好的,你已经耗尽了我的调试资源,所以我将回归基础。

Angular 2 HTTP Client 是他们展示如何进行 GET 请求的地方。然后 这里 是基于 Promise 的设置。

因此,根据这个,你的代码应该像这样。

item.service.ts 片段

getItems(): Promise<Item[]> {
    return this.http.get('http://apiurl', { withCredentials: true })
    .toPromise()
    .then(this.extractData)
    .catch(this.handleError);
}
private extractData(res: Response) {
  let body = res.json();
  return body || { };
}
private handleError (error: any) {
  // In a real world app, we might use a remote logging infrastructure
  // We'd also dig deeper into the error to get a better message
  let errMsg = (error.message) ? error.message :
    error.status ? `${error.status} - ${error.statusText}` : 'Server error';
  console.error(errMsg); // log to console instead
  return Promise.reject(errMsg);
}

item.component.ts

items: Item[] = [];

getItems(): void {
  this.itemService.getItems().then(items => this.items = items);
}


更新 #2

听起来原帖作者找到了问题所在,与其中一个变量的名称有关,似乎一个名为 entites 的变量可能会导致 Angular 2 出现问题。

"但是在真正的生产代码中,这个变量被称为 'entities'。一直以来,我都用这个名称。突发奇想,我将变量名称改为 'testentities',然后它就可以工作了!

所以为了确保,我测试了多种变化方式,每次都可以工作。然后我把它改回 'entities',错误再次出现了。"

entities: any{}; 

这是一个好主意,但恐怕没有起作用。items:Item [] = []; 部分看起来应该强制执行 items 为数组,但是完全相同的错误仍然存在。 - Damon Kaswell
@DamonKaswell 你的代码里有 Array.from(items) 这一部分吗? - Logan H
好的,我觉得我们离答案更近了。那种方法不起作用,因为错误在获取数据之前就已经被抛出了。所以我在 items: Item[] = []; 这一行设置了一个断点。有趣的是,如果我运行 this.items instanceof Array ,它返回 false! - Damon Kaswell
完成。我已经在多个步骤上添加了断点,现在它的状态是:Array.from(this.items) instanceof Array 在服务运行之前的每个点都返回 true。但是,在那一点上 - 在服务内部的 console.log(items) 上的断点 - 我突然遇到了 Uncaught TypeError: Cannot read property 'items' of null,这真的很奇怪。这.items 怎么可能突然变成 null 呢? - Damon Kaswell
感谢您尝试着解决问题!我正在按照 Angular 2 的示例重构代码,我会仔细阅读文档,如果我解决了这个问题,我会发布更新的。 - Damon Kaswell
显示剩余10条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接