这似乎很简单 . 我有一个Angular 6组件,它显示了一行表并有条件地显示了一些细节(产品的订单):
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: '[app-product-row]',
templateUrl: './product-row.component.html',
styleUrls: ['./product-row.component.css']
})
export class ProductRowComponent implements OnInit {
show: boolean = false;
@Input() product: any;
constructor() { }
ngOnInit() {
}
toggleDetail() {
this.show = !this.show;
}
get orders() {
return this.show ? this.product.orders : null;
}
}
问题是 toggleDetail()
函数对函数外的 show
变量没有影响 . 如果我添加一些 console.log()
行进行调试,就像这样......
toggleDetail() {
console.log(this.show);
this.show = !this.show;
console.log(this.show);
}
...每次用鼠标点击事件触发 toggleDetail()
函数时,它会记录'false'然后'true' . 但是在随后的点击中它会做同样的事情; show
变量实际上从未设置为 true
. 我错了什么?有关 this
关键字的事可能吗?
编辑:更多上下文
通过以下方式在父模板中使用* ngFor生成此组件:
<tbody app-product-row *ngFor="let p of group.products; let i = index;" [rownum]="i+1"></tbody>
模板本身看起来像这样:
<tr (click)="toggleDetail()">
<td>{{product.sku}}</td>
<td>{{product.oldest|date:'M/d/yyyy'}}</td>
<td>{{product.quantity}}</td>
<td>{{product.amount|currency:'USD':'symbol':'1.0-0'}}</td>
</tr>
<tr *ngFor="let o of orders">
<td>{{o.customer}}</td>
<td>{{o.planned_date}}</td>
<td>{{o.quantity}}</td>
<td>{{o.amount}}</td>
</tr>
这是我第一次以这种方式调用组件(作为另一个元素( <tbody>
)的属性而不是它自己的标签(例如 <app-product-row>
) . 也许这会以某种方式改变事物?
编辑2:也许* ngFor是问题?
我在组件和父组件中尝试了一个简单的测试,在父组件中创建一个布尔变量 booly
,并使用一个简单的onClick事件来切换它:
<p (click)="booly=!booly;">component-name: {{booly}}</p>
这在未作为循环的一部分实例化的父组件中正常工作 . 但是,在使用 *ngFor
指令实例化的每个子组件中,布尔变量无法切换 . 这包括一些用元素选择器调用的函数( <component-name>
)和一些带有属性选择器的函数(例如 <tr component-name>
),所以我认为它是问题 . 不过,我仍然难以理解如何解决它 .
3 回答
这里肯定有一些我们无法从提供的代码中看到的东西,但为了消除这种可能的原因,您可以这样做:
在你的模板中 .
尝试摆脱你的
get orders()
函数,而是让订单成为这样的数组EDIT: 尝试在html中显示当前的
this.orders
. 这可以帮助你弄清楚发生了什么 .typescript
html
长话短说,这个bug是
*ngFor
循环的结果或副作用 . 每次发生单击事件时,Angular都会简单地销毁并重新创建嵌套的表和行,因此本地组件变量不会持久存在 .我通过在父组件中完成所有循环逻辑(不是在循环中实例化)来解决这个问题,而不是每行上的true / false "show"变量,我向数据服务本身添加了一个参数(即"show details for this one"),所以详细信息行包含在数据中或不包含在数据中 . (因此不需要
*ngIf
. )我怀疑可能有另一种方法可以通过配置Angular的更改检测/更改处理设置来解决此问题,以防止组件被销毁和重新创建 . 如果有人知道,请回答!