如何修复"Cannot read property 'title' of undefined"错误。
如何修复"Cannot read property 'title' of undefined"错误。
我正在按照Mosh Hamedani的教程《Angular 4:从入门到专家》进行学习。
我正在尝试在编辑表单中显示产品的标题。
该产品存储在Firebase数据库中。
我对Angular还很陌生。
然而,当我打开编辑表单时,控制台显示以下错误:
错误类型:无法读取未定义的属性'title' 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)
以下是表单的一部分:
标题是必填项
这是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); <== 这似乎没有起作用 } save(product) { this.productService.create(product); this.router.navigate(["/admin/products"]); } ngOnInit() { } }
我该怎么做才能显示产品的标题?
问题原因:该错误是因为在启动时未初始化变量的值。这是因为变量首次从订阅中获取其值,而订阅需要一些时间才能获取值,因此在存在之前,视图就会渲染并尝试获取该值。
解决方法:首先为数据创建一个模型,然后初始化模型。可以参考在TypeScript中创建模型类的链接,根据链接中的说明创建模型。可以在启动时进行初始化以避免错误,或者创建另一个变量来强制视图等待变量。
代码示例:
import { Component, OnInit, OnDestroy } from '/core'; import { CategoryService } from 'src/app/category.service'; import { ProductService } from 'src/app/product.service'; import { Router, ActivatedRoute } from '/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中进行如下更改:
Title is required
可以根据需要对变量进行调整,以创建自己喜欢的加载指示器。
在解决"Cannot read property 'title' of undefined"问题时,我们进行了以下更改。首先,我们将product;
修改为product:any = {};
。其次,我们将snapshotChanges()
修改为valueChanges()
。具体更改如下:
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); // 这个方法似乎不起作用
经过这些更改,问题得到了解决。