观察到的类型错误:无法读取的未定义的属性观察到的类型错误:无法读取的未定义的属性(Observabl

2019-05-11 08:19发布

在我的角2的应用程序,我得到一个错误:

无法读取的未定义的属性“标题”。

这是一个非常简单的组件,只是想获得最低限度在这里工作。 它击中我的API控制器(好奇地多次),它似乎击中回调返回的对象之后。 我的console.log输出我期望的对象。 以下是完整的错误:

TypeError: Cannot read property 'title' of undefined
    at AbstractChangeDetector.ChangeDetector_About_0.detectChangesInRecordsInternal (eval at <anonymous> (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:10897:14), <anonymous>:31:26)
    at AbstractChangeDetector.detectChangesInRecords (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:8824:14)
    at AbstractChangeDetector.runDetectChanges (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:8807:12)
    at AbstractChangeDetector._detectChangesInViewChildren (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:8877:14)
    at AbstractChangeDetector.runDetectChanges (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:8811:12)
    at AbstractChangeDetector._detectChangesContentChildren (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:8871:14)
    at AbstractChangeDetector.runDetectChanges (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:8808:12)
    at AbstractChangeDetector._detectChangesInViewChildren (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:8877:14)
    at AbstractChangeDetector.runDetectChanges (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:8811:12)
    at AbstractChangeDetector.detectChanges (http://localhost:55707/lib/angular2/bundles/angular2.dev.js:8796:12)

服务(about.service.ts):

import {Http} from 'angular2/http';
import {Injectable} from 'angular2/core';
import {AboutModel} from './about.model';
import 'rxjs/add/operator/map';

@Injectable()
export class AboutService {
    constructor(private _http: Http) { }

    get() {
        return this._http.get('/api/about').map(res => {
            console.log(res.json()); // I get the error on the line above but this code is still hit.
            return <AboutModel>res.json();
        });
    }
}

成分(about.component.ts):

import {Component, View, OnInit} from 'angular2/core';
import {AboutModel} from './about.model';
import {AboutService} from './about.service';
import {HTTP_PROVIDERS} from 'angular2/http';

@Component({
    selector: 'about',
    providers: [HTTP_PROVIDERS, AboutService],
    templateUrl: 'app/about/about.html'
})

export class About implements IAboutViewModel, OnInit {
    public about: AboutModel;

    constructor(private _aboutService: AboutService) {}

    ngOnInit() {    
        this._aboutService.get().subscribe((data: AboutModel) => {
            this.about = data;
        });
    }
}

export interface IAboutViewModel {
    about: AboutModel;
}

的index.html

<script src="~/lib/systemjs/dist/system.src.js"></script>
<script src="~/lib/angular2/bundles/router.js"></script>
<script src="~/lib/angular2/bundles/http.js"></script>
<script src="~/lib/angular2/bundles/angular2-polyfills.js"></script>
<script src="~/lib/angular2/bundles/angular2.dev.js"></script>
<script src="~/lib/es6-shim/es6-shim.js"></script>
<script>
    System.config({
        packages: {
            app: {
                format: 'register',
                defaultExtension: 'js'
            },
            rxjs: {
                defaultExtension: 'js'
            }
        },
        map: {
            rxjs: "lib/rxjs"
        }
    });
    System.import('app/boot')
            .then(null, console.error.bind(console));
</script>

Answer 1:

请附上您的视图和模型下一次(应用程序/约/ about.html和about.model)。

如果返回的数组 ,可以用asyncPipe ,其中“预订可观察到的或承诺并返回它已发出的最新的值。当一个新的值被发射时,异步管标志着组件更改被检查”,因此视图将用新值进行更新。

如果要返回一个基本类型 (字符串,数字,布尔值)您也可以使用asyncPipe。

如果您正在返回一个对象我不知道任何方式使用asyncPipe,我们可以先使用异步管,结合安全导航操作 ?. 如下:

{{(objectData$ | async)?.name}}

但是,这看起来有点复杂,我们不得不重复,因为我们想要显示的每个对象的属性。

作为@pixelbits在评论中提到,你可以subscribe()以可观察到的控制器和所包含的对象存储到一个组件属性。 然后使用模板航行安全操作或NgIf:

service.ts

import {Injectable} from 'angular2/core';
import {Http} from 'angular2/http';
import 'rxjs/add/operator/map';  // we need to import this now

@Injectable()
export class MyService {
  constructor(private _http:Http) {}
  getArrayData() {
    return this._http.get('./data/array.json')
      .map(data => data.json());
  }
  getPrimitiveData() {
    return this._http.get('./data/primitive.txt')
      .map(data => data.text());   // note .text() here
  }
  getObjectData() {
    return this._http.get('./data/object.json')
      .map(data => data.json());
  }
}

app.ts

@Component({
  selector: 'my-app',
  template: `
    <div>array data using '| async':
      <div *ngFor="let item of arrayData$ | async">{{item}}</div>
    </div>
    <div>primitive data using '| async': {{primitiveData$ | async}}</div>
    <div>object data using .?: {{objectData?.name}}</div>
    <div *ngIf="objectData">object data using NgIf: {{objectData.name}}</div>`
  providers: [HTTP_PROVIDERS, MyService]
})
export class AppComponent {
  constructor(private _myService:MyService) {}
  ngOnInit() {
    this.arrayData$     = this._myService.getArrayData();
    this.primitiveData$ = this._myService.getPrimitiveData();
    this._myService.getObjectData()
      .subscribe(data => this.objectData = data);
  }
}

数据/ array.json

[ 1,2,3 ]

数据/ primitive.json

Greetings SO friends!

数据/ object.json

{ "name": "Mark" }

输出:

array data using '| async':
1
2
3
primitive data using '| async': Greetings SO friends!
object data using .?: Mark
object data using NgIf: Mark

Plunker



Answer 2:

它看起来像你提到about.title视图about.htmlabout的唯一变量后,被实例化http请求完成。 为了避免这种错误你可以用about.html<div *ngIf="about"> ... </div>



Answer 3:

以前的答案是正确的。 您需要检查变量定义之前在模板中使用它。 使用HTTP请求时,它需要时间来定义它。 使用* ngIf检查。 例子是从角设置有https://angular.io/docs/ts/latest/tutorial/toh-pt5.html和例子是http://plnkr.co/edit/?p=preview

<div *ngIf="hero">
  <h2>{{hero.name}} details!</h2>
<div>

您可以查看应用程序/英雄detail.component [TS和HTML]



文章来源: Observable type error: cannot read property of undefined