如何修复“无法读取未定义的属性‘标题’”
Posted
技术标签:
【中文标题】如何修复“无法读取未定义的属性‘标题’”【英文标题】:How to fix "Cannot read property 'title' of undefined" 【发布时间】:2019-10-03 16:53:31 【问题描述】:我正在关注 Mosh Hamedani 教程“Angular 4:初学者到专业人士”。
我在尝试编辑产品时尝试在表单中显示产品的标题。 该产品存储在 Firebase 数据库中。 我是 Angular 的新手。
但是,当我转到编辑表单时,控制台中出现此错误
ERROR TypeError: Cannot read property 'title' of undefined
at Object.eval [as updateDirectives] (ProductFormComponent.html:7)
at Object.debugUpdateDirectives [as updateDirectives] (core.js:23911)
at checkAndUpdateView (core.js:23307)
at callViewAction (core.js:23548)
at execComponentViewsAction (core.js:23490)
at checkAndUpdateView (core.js:23313)
at callViewAction (core.js:23548)
at execEmbeddedViewsAction (core.js:23511)
at checkAndUpdateView (core.js:23308)
at callViewAction (core.js:23548)
这是我的表格的一部分:
<div class="form-group">
<label for="title">Title</label>
<input #title="ngModel" [(ngModel)]="product.title" <== error here
name="title" id="title" type="text" class="form-control" required>
<div class="alert alert-danger" *ngIf="title.touched && title.invalid">
Title is required
</div>
</div>
这里是 product-form.component.ts
import Component, OnInit, OnDestroy from '@angular/core';
import CategoryService from 'src/app/category.service';
import ProductService from 'src/app/product.service';
import Router, ActivatedRoute from '@angular/router';
import take from 'rxjs/operators';
@Component(
selector: 'app-product-form',
templateUrl: './product-form.component.html',
styleUrls: ['./product-form.component.css']
)
export class ProductFormComponent implements OnInit
categories$;
product;
constructor(
categoryService: CategoryService,
private route: ActivatedRoute,
private productService: ProductService,
private router: Router)
this.categories$ = categoryService.getCategories();
let id = this.route.snapshot.paramMap.get('id');
if (id) this.productService.get(id).snapshotChanges().pipe(take(1))
.subscribe(p => this.product = p); <== this does not seem to be working
save(product)
this.productService.create(product);
this.router.navigate(["/admin/products"]);
ngOnInit()
如何显示产品的标题?
【问题讨论】:
试试 product['title'] 而不是 product.title @PareshGami 它与符号无关,似乎OP没有及时得到适当的响应! 控制台“产品”并检查“标题”键是否可用 【参考方案1】:它有一个简单的解决方案。显示错误是因为在初始化 html 组件时,产品还没有准备好(因为 api 调用需要一些时间来返回数据),所以它是未定义的。因此在html组件中使用?.
如下所示。
<div class="form-group">
<label for="title">Title</label>
<input #title="ngModel" [(ngModel)]="product?.title" <== error here
name="title" id="title" type="text" class="form-control" required>
<div class="alert alert-danger" *ngIf="title.touched && title.invalid">
Title is required
</div>
</div>
````
【讨论】:
【参考方案2】:您可以简单地在外部容器上添加 *ngIf="product"。只有在 prodcut 对象初始化时才会显示值。
【讨论】:
【参考方案3】:该错误是因为该值在启动时未初始化。 当变量从订阅中获取其第一个值时会发生这种情况,这需要一些时间才能获取值,因此视图呈现并尝试在该值存在之前获取该值。 我建议首先为您的数据创建一个模型,然后初始化您的模型 查看Creating model classes in typescript 了解如何创建模型。 您可以在启动时对其进行初始化以避免错误,或者创建另一个变量来强制视图等待该变量。
import Component, OnInit, OnDestroy from '@angular/core';
import CategoryService from 'src/app/category.service';
import ProductService from 'src/app/product.service';
import Router, ActivatedRoute from '@angular/router';
import take from 'rxjs/operators';
@Component(
selector: 'app-product-form',
templateUrl: './product-form.component.html',
styleUrls: ['./product-form.component.css']
)
export class ProductFormComponent implements OnInit
categories$;
product;
initialized : boolean = false
constructor(
categoryService: CategoryService,
private route: ActivatedRoute,
private productService: ProductService,
private router: Router)
this.categories$ = categoryService.getCategories();
let id = this.route.snapshot.paramMap.get('id');
if (id) this.productService.get(id).snapshotChanges().pipe(take(1))
.subscribe(p =>
this.initialized = true
this.product = p
);
save(product)
this.productService.create(product);
this.router.navigate(["/admin/products"]);
ngOnInit()
那么 html 将如下所示:
<div class="form-group">
<label for="title">Title</label>
<input #title="ngModel" *ngIf="initialized" [(ngModel)]="product.title"
name="title" id="title" type="text" class="form-control" required>
<div class="alert alert-danger" *ngIf="title.touched && title.invalid">
Title is required
</div>
</div>
您可以使用该变量来创建您喜欢的加载指示器
【讨论】:
【参考方案4】:变化
product;
到
product:any = ;
and (valueChanges() 而不是 snapshotChnages())
if (id) this.productService.get(id).snapshotChanges().pipe(take(1))
.subscribe(p => this.product = p);
到
if (id) this.productService.get(id).valueChanges().pipe(take(1))
.subscribe(p => this.product = p); <== this does not seem to be working
已解决问题
【讨论】:
【参考方案5】:你也可以使用
product:any = ;
【讨论】:
在哪里?为什么?请添加详细信息。 Hello Nino,您可以在其中定义product
变量。只需替换为product:any = ;
以上是关于如何修复“无法读取未定义的属性‘标题’”的主要内容,如果未能解决你的问题,请参考以下文章
我的 Apollo 服务器的订阅不起作用:无法读取未定义的属性“标题”