【问题标题】:Angular 6 - Prevent Function Change on ClickAngular 6 - 点击时防止功能更改
【发布时间】:2019-03-24 11:58:09
【问题描述】:

我有一个返回随机数的function

@Component({
    selector: '...',
    templateUrl: '...',
    styleUrls: ['...'],
    changeDetection: ChangeDetectionStrategy.OnPush,
})
export class Component {

    randomPerc(min, max): number {
        return Math.floor(Math.random() * (max - min + 1) + min);
    }

}

我只在这样的 HTML 模板中使用这个函数(在很多地方):

<div [style.width.%]='randomPerc(20, 70)'></div>

“问题”是,只要我点击页面上的某个位置,百分比就会发生变化。但我想阻止这种行为 - 我希望在第一次调用函数后百分比是静态的

我想创建一个常量全局变量,但这不会起作用,因为我多次使用这个函数。 (我希望每次使用一个不同的随机数)

【问题讨论】:

  • 你能发布你的组件代码吗?
  • 除了装饰器中的`changeDetection: ChangeDetectionStrategy.OnPush`之外,这个组件绝对没有什么特别之处

标签: html angular typescript angular6


【解决方案1】:

方法 1 - 缓存 Map 对象中的值

您可以为每个元素使用不同的键调用该方法,将结果缓存在Map 对象中,并在为同一元素再次调用该方法时重用它:

<div [style.width.%]="randomPerc('key1', 20, 70)"></div>
<div [style.width.%]="randomPerc('key2', 10, 50)"></div>
<div [style.width.%]="randomPerc('key3', 25, 90)"></div>

<div *ngFor="let item of items; let i = index">
  <div [style.width.%]="randomPerc('item' + i, 25, 90)"></div>
</div>
private widths = new Map<string, number>();

randomPerc(key: string, min: number, max: number): number {
  if (!this.widths.has(key)) {
    this.widths.set(key, Math.floor(Math.random() * (max - min + 1) + min));
  }
  return this.widths.get(key);
}

请参阅this stackblitz 以获取演示。


方法 2 - 使用自定义指令

另一种方法是定义自定义指令。在下面的示例中,最小和最大百分比宽度被定义为具有默认值的两个输入参数。由于 style 属性仅在 ngOnInit 中设置在元素上,因此在更改检测后不会对其进行修改。

import { Directive, Input, ElementRef, OnInit } from '@angular/core';

@Directive({
  selector: "[randomWidth]"
})

export class RandomWidthDirective implements OnInit {

  @Input() minRandom: number = 20;
  @Input() maxRandom: number = 70;

  constructor(private el: ElementRef) { }

  ngOnInit() {
    let value = Math.floor(Math.random() * (this.maxRandom - this.minRandom + 1) + this.minRandom);
    this.el.nativeElement.style.width = `${value}%`;
  }
}

该指令应用于模板中的元素,使用默认参数或用不同的值覆盖它们:

<div randomWidth></div>
<div randomWidth [minRandom]="10"></div>
<div randomWidth [minRandom]="5" [maxRandom]="95"></div>

请参阅this stackblitz 以获取演示。

【讨论】:

  • 好主意,确实。但我认为这种方法对我来说是不可持续的,因为我经常(在循环中)使用该函数
  • “循环”是指ngFor?
  • 是的,我的意思是我可以通过index 传递不同的键,但我不喜欢拥有一个包含 500 多个项目的数组的想法
  • 检查this stackblitz 以获得带有指令的解决方案。如果它适合您,我会将其添加到我的答案中。
猜你喜欢
  • 2016-11-24
  • 1970-01-01
  • 2014-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-13
相关资源
最近更新 更多