为什么不能使用toggle()函数设置此布尔组件变量?

时间:2018-06-20 18:18:58

标签: angular this

这似乎很简单。我有一个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>

这在作为循环一部分实例化的父组件 not 中正常工作。但是,在用*ngFor实例化的每个子组件中,布尔变量都无法切换。这包括一些使用元素选择器(<component-name>)调用和一些使用属性选择器(例如<tr component-name>)调用的方式,所以我认为这是循环的问题。不过,我仍然对如何解决感到困惑。

3 个答案:

答案 0 :(得分:0)

这里肯定存在某些事情,我们从提供的代码中看不到,但是要消除这种情况的大多数可能原因,您可以这样做:

<tr (click)="show = !show">

在您的模板中。

答案 1 :(得分:0)

尝试摆脱您的get orders()函数,而将订单变成这样的数组

orders = [];
toggleDetail() {
  this.show = !this.show;
  this.orders = this.show ? this.product.orders : [];
}

编辑:尝试在HTML中显示当前的this.orders。这可以帮助您了解正在发生的事情。

打字稿

orders = [];
temp = ''; //new
toggleDetail() {
  this.show = !this.show;
  this.orders = this.show ? this.product.orders : [];
  console.log(this.orders); //new
  temp = JSON.stringify(this.orders); //new
}

html

{{temp}} <!--new-->
<tr *ngFor="let o of orders">
   ...

答案 2 :(得分:0)

长话短说,该错误是*ngFor循环的结果或副作用。每次单击事件发生时,Angular只是破坏并重新创建我的嵌套表和行,因此本地组件变量根本就不会持久。

我通过在父组件中执行所有循环逻辑(而不是在循环中实例化)来解决此问题,我在数据服务本身中添加了一个参数,而不是在每一行上使用true / false“ show”变量即“显示此详细信息”),因此详细信息行要么包含在数据中,要么不包含在数据中。 (因此不需要*ngIf。)

我怀疑可以通过配置Angular的更改检测/更改处理设置来防止组件被破坏和重新创建来解决此问题。如果有人知道,请发布答案!