异步管道不会将对象数据填充到模板中 [英] Async pipe does not fill object data into template

查看:21
本文介绍了异步管道不会将对象数据填充到模板中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谁能帮我看看我的模板中是否有语法错误?它不会出错,但也不会将数据填充到模板中:

<h2>{{英雄}}</h2><h2>{{hero.name}} 详情!</h2><div><label>_id: </label>{{hero._id}}</div><div><标签>名称:</label><input [(ngModel)]="hero.name" placeholder="name"/>

<button (click)="goBack()">Back</button>

组件代码

导出类 HeroDetailComponent 实现 OnInit {错误消息:字符串;//@输入()英雄:可观察的<英雄>;构造函数(私有_heroService:HeroService,私人_routeParams:RouteParams){}ngOnInit() {让 _id = +this._routeParams.get('_id');this._heroService.loadHero(_id);this.hero = this._heroService.hero$;this.hero.subscribe(data =>控制台日志(数据))}

console.log(data) 打印:

<块引用>

对象 {_id: 11, name: "Mr. Nice"}

这意味着数据被正确检索.

块也会出现,这意味着 *ngIf 将对象视为非空.

<h2>{{hero}}</h2> 显示 [object Object].

但是为什么 {{hero.name}} 没有显示?

解决方案

对象在使用异步管道时有点棘手.对于包含数组的 Observable,我们可以使用 NgFor 并创建一个本地模板变量(下面的hero),在异步管道从 Observable 中提取数组后,该变量会被分配给数组的每个项目.然后我们可以在模板的其他地方使用该变量:

{{英雄名字}}

<!-- 我们不能在这里使用 hero,在 NgFor div 之外 -->

但是对于包含单个对象的 Observable,我不知道有什么方法可以创建将引用该对象的本地模板变量.相反,我们需要做一些更复杂的事情:

{{(hero | async)?.name}}

而且我们需要为我们想要显示的对象的每个属性重复这一点.(上面这行假设组件属性 hero 是一个 Observable.)

使用组件逻辑将对象(即在 Observable 内部,hero$ 下面)分配给组件的属性可能更容易:

this._heroService.hero$.subscribe(data => this.hero = data.json());

然后使用 NgIf 或 Elvis/安全导航操作符在视图中显示数据:

<div *ngIf="hero">{{hero.name}}</div><!-- 或--><div>{{hero?.name}}</div>

Can anyone help me see if there is a syntax error here in my template? It does not give error, but does not fill in data into the template either:

<div *ngIf="(hero | async)">
  <h2>{{hero}}</h2>
  <h2>{{hero.name}} details!</h2>
  <div>
    <label>_id: </label>{{hero._id}}</div>
  <div>
    <label>name: </label>
    <input [(ngModel)]="hero.name" placeholder="name" />
  </div>
  <button (click)="goBack()">Back</button>
</div>

Component code

export class HeroDetailComponent implements OnInit {
    errorMessage: string;

    //@Input() 
    hero: Observable<Hero>;

    constructor(
        private _heroService: HeroService,
        private _routeParams: RouteParams) {
    }

    ngOnInit() {
        let _id = +this._routeParams.get('_id');
        this._heroService.loadHero(_id);
        this.hero = this._heroService.hero$;
        this.hero.subscribe(data => 
           console.log(data)
        )
    }

The console.log(data) prints:

Object {_id: 11, name: "Mr. Nice"}

which means that the data is correctly retrieved.

The <div> block also shows up, which mean *ngIf sees the object as non-empty.

<h2>{{hero}}</h2> shows [object Object].

But why the {{hero.name}} is not showing?

解决方案

Objects are a bit tricky with the async pipe. With an Observable that contains an array, we can use NgFor and create a local template variable (hero below) that gets assigned each item of the array after the async pipe extracts the array from the Observable. We can then use that variable elsewhere in the template:

<div *ngFor="let hero of heroes | async">
  {{hero.name}}
</div>
<!-- we can't use hero here, outside the NgFor div -->

But with an Observable that contains a single object, I'm not aware of any way to create a local template variable that will reference that object. Instead, we need to do something more complicated:

<div>{{(hero | async)?.name}}</div>

And we would need to repeat that for each property of the object we want to display. (The above line assumes that component property hero is an Observable.)

It is probably easier to assign the object (that is inside the Observable, hero$ below) to a property of the component, using component logic:

this._heroService.hero$.subscribe(data => this.hero = data.json());

and then use NgIf or the Elvis/safe navigation operator to display the data in the view:

<div *ngIf="hero">{{hero.name}}</div>
<!-- or -->
<div>{{hero?.name}}</div>

这篇关于异步管道不会将对象数据填充到模板中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆