且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

为什么 ngClass 无限期地调用函数?

更新时间:2023-08-31 21:49:52

如果您的绑定中有一个方法,则每次更改检测运行时都会调用该方法.

如果您需要通过点击另一个父按钮来更新父按钮,试试这个:

模板:

<button (click)="updateLockClass()">点击更新</button><button type="button" [ngClass]="lockClass">带有lockClass"的按钮</button>

应用组件:

导出类 AppComponent {锁类 = "";检查类(数量){返回数 == 2;}更新锁类(){this.lockClass = this.checkClass(2) ?lockClass2":lockClass";}}

如果您需要通过更新解析为子组件的父值来更新子按钮,请尝试以下操作:

父组件:

<app-child [childMessage]="parentMessage"></app-child><input [(ngModel)]="parentMessage">

child.component.html

<button type="button" [ngClass]="childClass">带有childClass"的子按钮</button>

child.component.ts

import { Component, Input, OnChanges, SimpleChanges } from "@angular/core";@零件({选择器:app-child",templateUrl: "./child.component.html",styleUrls: ["./app.component.css"]})导出类 ChildComponent 实现 OnChanges {childClass = "";@Input() childMessage: 字符串;检查类(数量){返回数 == 2;}更新子类(){this.childClass = this.checkClass(2) ?"lockClass3" : "lockClass";}构造函数(){}ngOnChanges(更改:SimpleChanges){console.log('检测到更改:', changes.childMessage);if (changes.childMessage.currentValue != "改变父值!") {this.updateChildClass();}}}

codesandbox 链接:https://codesandbox.io/s/1y4wnz423

I am attempting to add a class based off of whether or not a value is present in storage, or set to a specific value. I am attempting to use [ngClass] for this. For some reason, my function to check the storage is getting called infinitely. What is causing this behavior and how can I stop it?

One example of the usage in my html file:

<div id="level2" class="cell middle" [ngClass]="{'locked': checkLevel(2)}">

checkLevel function:

checkLevel(level): any{
        console.log("checkLevel(" + level + ")");
        var result = this.storage.getLevel(level.toString());
        console.log(result);
        if (result == null || result['status'] == 'locked'){
            return true;
        } else {
            return false;
        }
    }

getLevel function:

getLevel(level:string):any{
        console.log("Inside getLevel.");
        this.storage.get('games' + level).then((val) => {
            console.log(val);
            return val;
        });
    }

Output to the console:

checkLevel(10)
storage.ts:20 Inside getLevel.
levels.ts:28 undefined
levels.ts:26 checkLevel(11)
storage.ts:20 Inside getLevel.
levels.ts:28 undefined
levels.ts:26 checkLevel(12)
storage.ts:20 Inside getLevel.
levels.ts:28 undefined
levels.ts:26 checkLevel(13)
storage.ts:20 Inside getLevel.
levels.ts:28 undefined
levels.ts:26 checkLevel(14)
storage.ts:20 Inside getLevel.
levels.ts:28 undefined

And it just keeps doing that forever. Cycling through all of the places that I use the [ngClass]. The actual levels page is never displayed.

--CONTEXT UPDATE--

I am using this on a page that contains a slider with 3 slides. Each slide contains 9 divs or 'cells' that represent a single level. There are 27 levels and that will never change, so the levels are static elements on the page (not loaded dynamically). Each level (except the first) is initially locked. Completing a level will unlock the next one. Or, levels can be unlocked by using the in game currency. So I need to check the local storage and set the locked class if there is no data for the level, or if the level has a status of locked. If it is unlocked, do not apply the locked class.

I just need some way to dynamically change classes based off of the level data that I am returned.

If you have a method in your binding, it will be called every time change detection runs.

If you need to update parent button by clicking on another parent button, try this:

Template:

<button (click)="updateLockClass()">Click to update</button>
<button type="button" [ngClass]="lockClass">Button with "lockClass</button>

App component:

export class AppComponent {
  lockClass = "";

  checkClass(num) {
    return num == 2;
  }

  updateLockClass() {
    this.lockClass = this.checkClass(2) ? "lockClass2" : "lockClass";
  }
}

If you need to update child button by updating parent value that gets parsed into child component, try this:

parent component:

<app-child [childMessage]="parentMessage"></app-child>
    <input [(ngModel)]="parentMessage">

child.component.html

<button type="button" [ngClass]="childClass">Child Button with "childClass"</button>

child.component.ts

import { Component, Input, OnChanges, SimpleChanges } from "@angular/core";

@Component({
  selector: "app-child",
  templateUrl: "./child.component.html",
  styleUrls: ["./app.component.css"]
})
export class ChildComponent implements OnChanges {
  childClass = "";
  @Input() childMessage: string;

  checkClass(num) {
    return num == 2;
  }

  updateChildClass() {
    this.childClass = this.checkClass(2) ? "lockClass3" : "lockClass";
  }

  constructor() {
  }

  ngOnChanges(changes: SimpleChanges) {
    console.log('Change detected:', changes.childMessage);
    if (changes.childMessage.currentValue != "Change parent value!") {
      this.updateChildClass();
    }
  }
}

Link to codesandbox: https://codesandbox.io/s/1y4wnz423

相关阅读

推荐文章