我有一个名为zoomdetails的组件,其中包含产品的特定详细信息 当我点击产品图片时,zoomdetails组件会显示并包含所点击产品的详细信息
所以我使用路由并将产品的ID添加到URL
问题是:当我从服务加载产品arraylist并尝试通过其id获取产品并循环arraylist时出现错误并指示无法读取属性' length'未定义的
这里是zoomdetails.component.ts代码: (我添加了一些log.console注释以查看结果)
export class ZoomdetailsComponent implements OnInit {
x: string="";
produitzoom:IProduct;
produits:IProduct[];
errormessage1 :string ;
currentId : number;
constructor(private _route:ActivatedRoute,private _router:Router,private _productServic:ProductdataService)
{
console.log("Logging the route : " + JSON.stringify(_route.snapshot.params));
this.currentId = +_route.snapshot.params['id'];
console.log("Logging the current ID : " + this.currentId)
this._productServic.getProducts()
.subscribe(productss => this.produits=productss ,error=>this.errormessage1= <any>error);
console.log("************************************************************************************")
}
Myspan(){
this._router.navigate(['/']);
}
find (id:number,P:IProduct[]) :IProduct{
console.log("+++++++DANS FIND ERROR +++++++++++++++++++++++++")
for (let product of P )
{
if (product.idpr==id )
{
return product;
}
}
}
ngOnInit() {
console.log("-------------DANS NGONINITTT-------------------------------------------------------------")
this.produitzoom=this.find(this.currentId,this.produits)
console.log(this.produitzoom.productName)
console.log("--------------------------------------------------------------------------")
}
&#13;
这是我的zoomdetails组件.html
<router-outlet></router-outlet>
<div id="zoom" class="modal">
<!-- Modal content -->
<div class="modal-content">
<span class="close" (click)="Myspan()">×</span>
<div class="container">
<div class="row">
<div class="col-md-4 item-photo">
<img src={{produitzoom.imgUrl}} style="width:360px;height:650px;">
</div>
<div class="col-md-6" style="border:0px solid rgba(163, 152, 152, 0.856)">
<span class="pull-right">
<!-- Datos del vendedor y titulo del producto -->
<h1>{{produitzoom.productName}}</h1>
<h4 style="color:#337ab7"> {{produitzoom.author}} <small style="color:#337ab7">(50 ventes)</small></h4>
<!-- Precios -->
<h2 class="title-price"><small>Price</small></h2>
<h3 style="margin-top0px">{{produitzoom.price}} $</h3>
<br> <br>
<!-- Detalles especificos del producto -->
<div class="section" style="background:rgb(222, 228, 222);">
<h5 class="title-attr" >
<div>
<br>
{{produitzoom.description}}
<br> <br>
</div>
</h5>
</div>
<br><br>
<!-- Botones de compra -->
<script>
console.log("Test of value : " + JSON.stringify(produitzoom))
</script>
<button class="btn btn-success right" [routerLink]="['/Authentification',produitzoom]">
<span class="glyphicon glyphicon-shopping-cart"></span> Add to Cart
</button>
</span>
<br> <br> <br> <br>
<ul class="menu-items">
<li class="active">Customers Reviews</li>
</ul>
<div style="width:100%;border-top:1px solid silver">
<p style="padding:15px;">
<small>
Stay connected either on the phone or the Web with the Galaxy S4 I337 from Samsung. With 16 GB of memory and a 4G connection, this phone stores precious photos and video and lets you upload them to a cloud or social network at blinding-fast speed. With a 17-hour operating life from one charge, this phone allows you keep in touch even on the go.
With its built-in photo editor, the Galaxy S4 allows you to edit photos with the touch of a finger, eliminating extraneous background items. Usable with most carriers, this smartphone is the perfect companion for work or entertainment.
</small>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
&#13;
这些是错误:
Logging the route : {"id":"1"} zoomdetails.component.ts:22 Logging the current ID : 1 zoomdetails.component.ts:25 ************************************************************************************ zoomdetails.component.ts:50 -------------DANS NGONINITTT------------------------------------------------------------- zoomdetails.component.ts:38 +++++++DANS FIND ERROR +++++++++++++++++++++++++ ZoomdetailsComponent_Host.html:1 ERROR TypeError: Cannot read property 'length' of undefined (from the find method )
错误类型错误:无法读取属性&#39; imgUrl&#39;未定义的(来自html文件produitzoom.imgurl)
我应该怎么做!
答案 0 :(得分:1)
首先,关于imgUrl
错误,因为最初produitzoom
未定义,并且在异步调用后获得它的值,您可以将绑定的值更改为这个:[src]="produitzoom? produitzoom.imgUrl : null"
。
还有关于另一个错误,你在this.produitzoom=this.find(this.currentId,this.produits)
函数中调用了ngOnInit
,但同样重要的是,在组件的开头部分produits
也未定义的事实&# 39; s生命周期,并在异步调用后获取它的值。您应该将this.find()
移动到订阅的成功。像这样的东西:
productss => {
this.produits=productss;
this.produitzoom = this.find(this.currentId,this.produits)
}
注意!! 强>
它也非常重要,并建议如果您订阅了一个observable,则在该组件的生命周期(ngOnDestroy
函数内)的末尾取消订阅它。否则,这会导致内存韭菜和无法纠正的错误......你可以通过定义订阅属性来做到这一点:
productsSubscription: Subscription;
别忘了从Subscription
导入rxjs/subscription
。然后将订阅分配给此属性,如:
this.productsSubscription = this._productServic.getProducts()
.subscribe(.....);
并且在ngOnDestroy中:
ngOnDestroy(){
if(this.productsSubscription){
this.productsSubscription.unsubscribe();
}
}
让那里if
来防止任何与未定义相关的错误。
答案 1 :(得分:0)
问题是您在构造函数中加载产品,这是异步的。然后在您稍后调用的ngOnInit
函数中使用这些已加载产品的结果,但不幸的是它们似乎尚未加载。因此,您的P
数组尚未存在,因此您在for循环中使用了一个未定义的对象,这是无效的。
ngOnInit() {
console.log("-------------DANS NGONINITTT-------------------------------------------------------------")
// --> here you use the products from the constructor
// but they are not loaded yet, because the loading process takes time and is asynchronous
this.produitzoom=this.find(this.currentId,this.produits)
console.log(this.produitzoom.productName)
console.log("--------------------------------------------------------------------------")
}
您应该做的是将产品加载到ngOnInit
功能中。在那里你可以等待结果,然后调用find函数。
nOnInit(){
// don't subscribe in the constructor, do it in the ngOnInit
this._productServic.getProducts().subscribe(productss => {
// now the results are here and you can use them
this.produits = productss;
// only then you can call the find function safely
this.produitzoom = this.find(this.currentId, this.produits)
}, error => this.errormessage1 = <any>error);
}