【问题标题】:Access Angular2 object?访问 Angular2 对象?
【发布时间】:2016-10-06 02:02:14
【问题描述】:

我想保存和访问 Angular2 对象,但我的值未定义。我正在获取一个对象,但这无法访问,例如数组。我怎样才能将它作为数组?

Node.js api.js

api.get('/getData', function(req, res){
  res.send({name:'test'})
});

数据服务 PassProfileDataService.ts

import {Component, Injectable} from '@angular/core'
import { Http} from "@angular/http";


@Injectable()
export class PassProfileDataService {

constructor(private http: Http) {}

getItems(){
    return this.http.get('/api/getData').map((res:any) => res);
}
}

使用服务的组件

import {Component, Input, OnInit} from '@angular/core';
import {PassProfileDataService} from '../common/PassProfileDataService';


@Component({
styleUrls:['/assets/css/bootstrap.css', '/assets/css/profile.css'],
    selector: "profile",
    templateUrl: `client/components/profile/profile.component.html`

})

export class ProfileComponent implements OnInit {

items:any;

constructor(private _sharedService: PassProfileDataService){}

ngOnInit(){
    this.items = this._sharedService.getItems();
    console.log(this.items + ' test');
}

}

视图组件profile.component.html

<div *ngFor="let i of items">
{{i.name}} 
</div>

我收到以下异常:

core.umd.js:3462 例外:找不到“object”类型的不同支持对象“[object Object]”。 NgFor 只支持绑定到 Arrays 等 Iterables。

【问题讨论】:

    标签: angular


    【解决方案1】:

    this.items.subscribe(...) 是异步的,这意味着它现在不会运行该代码。 this.items 是一个Observable,简而言之,当某事最终发生时,您可以收到通知并在事件发生时“观察”事件或一系列事件。在这种情况下,它看起来很像对getUserWishList() 的响应的承诺。我写了很多看起来像这样的代码。

    如果一切按计划进行,最终对 observable 的订阅将触发,this.data 将等于 value,但我可以保证,当您尝试打印它时,它不会在下一行发生。

    this.items.subscribe(value =&gt; console.log(value)); 之所以有效,是因为当事件最终触发时,您具有价值并可以打印它。

    this.items.subscribe(value =&gt; this.data = value); 也可以。最终。它只是不会像您期望的那样快速完成。

    你可以稍微修改一下你的代码:

    this.items.subscribe(value => {
      this.data = value;
      console.log(this.data);
    });
    

    您将在控制台中看到该值,如果有任何内容绑定到this.data,它也应该反映视图中的数据。不过这可能有点棘手,如果在 Observable 返回之前,如果 this.data 没有保存任何内容,则尝试在视图中绑定 data.name 会出现错误。

    【讨论】:

    • 我收到以下错误 client/components/profile/profile.component.ts(27,6): error TS2322: Type 'any[]' is notassignable to type 'Observable'。 [1] client/components/profile/profile.component.ts(27,6):错误 TS2322:类型“any[]”不可分配给类型“Observable”。 [1] 类型“any[]”中缺少属性“_isScalar”。另外我怎样才能访问 name 属性?
    • @Tony 这是一个更复杂的打字问题,可能值得提出一个新问题。您必须向我们展示更多代码才能看到 getUserWishList 实际返回的内容(一个 Observable,但泛型类型是什么?即 Observable>)以及 value 到底是什么。
    • @Tony,从您的问题中的console.log 图像来看,value 只是一个对象而不是数组。由此我假设 value 是 anythis.data 不应该是任何类型的 Observable,this.data 应该只是 any。或者更好的是,一个正确定义的接口。
    • 嗨,Corey,请参阅上面的代码。我添加了我正在尝试做的代码的完整示例。我得到一个对象 [object Object] 但我无法遍历这些。
    • 1) 在您的服务中,不要只返回响应对象,您应该使用res.text()res.json(),这样您才能真正拥有响应数据。 2) 仔细检查 API 是否实际上返回了一个对象数组。您将 this.items 设置为对象而不是数组,因此 ngFor 无法对其进行迭代。 3)这是我个人的观点,我发现它产生了更易于维护的代码:尽可能少地使用any。尽可能明确,以便 Typescript 可以在问题出现之前帮助发现问题。使用 Typescript 的 noImplicitAnynoImplicitReturns 编译器标志。
    【解决方案2】:

    这是因为框架的异步行为。代码不会等待您的服务返回。它继续下一条语句,在那个时间点,“数据”是未定义的。更改以下代码:

    this.items.subscribe(value => this.data = value);
    console.log(this.data);
    

    到:

    this.items.subscribe(value => {
    this.data = value;
    console.log(this.data);
    });
    

    你看出区别了吗?我将console.log 移动到success 服务调用块。这是使您的代码以同步方式运行的一种快速方法。当您需要时,还有其他方法可以在您的代码中引入同步行为,即Observable.forkJoin。希望你明白了。

    【讨论】:

      【解决方案3】:

      TypeScript 允许您在定义函数时访问外部函数范围,使用箭头符号,通过将参数包装在括号中。

      要保存数据的值,只需使用:

      this.items.subscribe((value) => this.data = value);
      

      要保存数据并在数据到达后立即输出,您可以使用:

      this.items.subscribe((value) => {
          this.data = value;
          console.log(this.data);
      });
      

      【讨论】:

        猜你喜欢
        • 2016-07-02
        • 2016-07-06
        • 1970-01-01
        • 2016-07-28
        • 2023-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-23
        相关资源
        最近更新 更多