【问题标题】:Angular4 *ngIf not working / Variable is undefinedAngular4 *ngIf 不工作/变量未定义
【发布时间】:2017-10-22 21:00:16
【问题描述】:

我正在尝试获取所选项目的视图详细信息。 *ngIf 语句似乎不起作用。它呈现一个普通页面,而不是所选“人”的“详细信息”。 出于测试目的,我将 *ngIf 语句换成了真正的 *ngIf="1",然后我设法渲染了页面标记(它有效!),但是

{{ person.name }} and `{{ person.id }}`

没用。 所以,看起来我的 details.htmlperson 变量一无所知。

应该怎么做才能正确呈现 details.html 组件?

person.service.ts

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';

import { IPerson } from '../persons/person';

@Injectable()
export class PersonService {
  private _personUrl = './assets/persons.json';

  constructor(private _http:Http){}

  getPersons(): Observable<IPerson[]> {
    return this._http.get(this._personUrl)
    .map((response: Response) => <IPerson[]>response.json().personsData)
  }

   getPerson(id:number): Observable<IPerson>{
    return this.getPersons()
    .map(persons => persons.find(person => person.id === id));
  }

}

details.component.html

<div *ngIf="person" class="container">
  <h3>Person Details</h3>
  <div class="col-md-12">
     <div>{{ person.name }}</div>
     <div>{{ person.id }}</div>
  </div>

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

details.component.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { PersonService } from '../service/person.service';
import { IPerson } from '../persons/person';

@Component({
   selector: 'app-details',
   templateUrl: './details.component.html',
  styleUrls: ['./details.component.css'] 
})
export class DetailsComponent implements OnInit {
  public person: IPerson;

  constructor(
    private _PersonService: PersonService,
    private route: ActivatedRoute
    ) { }

  ngOnInit(): void {
    this.route.params.forEach((params: Params) => {
        let id = +params['id'];
        this._PersonService.getPerson(id)
    .map(person => this.person = person).subscribe();
    })
  }


}

persons.json

{
  "personsData" : [
    {
      "id": 1,
      "name": "KC"
    },
    {
      "id": 2,
      "name": "KN"
    },
    {
      "id": 3,
      "name": "DG"
    }]
 }

UPD 似乎问题在于 details.component.ts 中的 person 变量未定义,尽管我在导出的类中声明了它。

【问题讨论】:

  • 您的 html 文件的名称是 details.component.html 还是 details.html?这有点令人困惑。 details.html 到处都是,但组件代码中有details.component.html
  • @R.Richards 很抱歉让您感到困惑。其实就是details.component.html,只是为了缩短代码才这么写的。

标签: javascript angular angular2-template angular2-services angular-ng-if


【解决方案1】:

ActivatedRouteparams 属性返回一个您需要订阅的 observable。所以我们必须把你的代码改成这样:

this.route.params.subscribe(...)

还建议使用paramsMap 而不是params,正如其名称所描述的那样,它将返回一个地图。所以我们可以进一步改成这样:

this.route.paramMap.subscribe(paramMap => paramMap.get('id'))

现在我们在地图上使用get 方法,将密钥传递给它,在这种情况下是您的参数的名称,最后,这基本上会给我们相同的结果。

另一个完全错误的代码是map 运算符。在使用 Observables 时,我们使用 map 运算符来改变发出的数据。例如,这个 observable 正在发射一个 Person。如果您只想要人名,您可以像这样使用地图运算符:

.map(person => person.name)

如果你不习惯这种语法,那么这是等价的:

.map(person => {return person.name})

收到所需数据后应该运行的代码放在 subscibe 中,它接受三个参数,但我们通常只关心前两个,即成功和错误回调函数。您的最终代码应如下所示:

this.route.paramMap.subscribe(params => 
    this._PersonService.getPerson(+params.get('id'))
        .subscribe((person) => this.person = person, () => {  //do something on error}))

【讨论】:

  • 终端抛出错误:“字符串”类型的参数不可分配给“数字”类型的参数。对于这一行:this._PersonService.getPerson(params.get('id'))
  • +params.get('id')
  • 那是我的错。加号运算符表示不同的东西,但在这种情况下,它会为您提供某物的数值。使用 get 方法检索的参数将始终是一个字符串 ('1'),由于我们要将其转换为数字,因此我们应用加号运算符。
  • 它也应该可以工作,谢谢!但似乎我的问题是地图(或您的变体 - 订阅)函数中的“人”变量未定义。
【解决方案2】:

您的数据是异步的,因此您必须使用管道异步来呈现它:

https://angular.io/api/common/AsyncPipe

只需将该管道添加到插值中即可。

【讨论】:

  • 我把它改成了 {{ (person|async)?.title }},还是不行
  • 那么,如果不在插值内,在哪里使用管道?
  • 我将 Pipe 导入到 details.component.ts 中,对吧?并尝试将其用作 {{ person.name |异步}}。不工作(
  • 但是你有个人数据吗?让我们在地图功能中做控制台登录细节组件。
  • 嗯...人未定义
猜你喜欢
  • 1970-01-01
  • 2022-11-29
  • 2018-06-18
  • 2021-08-07
  • 2015-09-19
  • 2020-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多