首页 文章

为什么我不能用我的toggle()函数设置这个布尔组件变量?

提问于
浏览
1

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

  • 0

    这里肯定有一些我们无法从提供的代码中看到的东西,但为了消除这种可能的原因,您可以这样做:

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

    在你的模板中 .

  • 0

    尝试摆脱你的 get orders() 函数,而是让订单成为这样的数组

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

    EDIT: 尝试在html中显示当前的 this.orders . 这可以帮助你弄清楚发生了什么 .

    typescript

    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">
       ...
    
  • 0

    长话短说,这个bug是 *ngFor 循环的结果或副作用 . 每次发生单击事件时,Angular都会简单地销毁并重新创建嵌套的表和行,因此本地组件变量不会持久存在 .

    我通过在父组件中完成所有循环逻辑(不是在循环中实例化)来解决这个问题,而不是每行上的true / false "show"变量,我向数据服务本身添加了一个参数(即"show details for this one"),所以详细信息行包含在数据中或不包含在数据中 . (因此不需要 *ngIf . )

    我怀疑可能有另一种方法可以通过配置Angular的更改检测/更改处理设置来解决此问题,以防止组件被销毁和重新创建 . 如果有人知道,请回答!

相关问题