You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular15中ngx-ui-switch加载时自动触发函数的问题求助

Angular 15中ngx-ui-switch初始化自动触发ngModelChange的问题

项目环境

  • Angular版本:15
  • ngx-ui-switch版本:^14.0.3(导入自UiSwitchModule)

相关代码

HTML模板代码

<table *ngIf="child.submenu">
  <tr *ngFor="let subchild of child.submenu.items" class="isShown" [ngClass]="{'has-sub':(subchild.submenu),'active': subchild.isSelected && !subchild.submenu, 'open': subchild.isOpen && subchild.submenu}">
    <td>
      <a class="menu-item">{{subchild.title}}</a>
      <table *ngIf="subchild.submenu && !subchild.excludeInVertical" class="menu-content">
        <tr *ngFor="let subchild of subchild.submenu.items" [ngClass]="{'active': subchild.isSelected && !subchild.submenu}">
          <td>
            <a class="menu-item" *ngIf="!subchild.event" routerLink="{{subchild.page}}" (click)="toggleMenu($event, subchild, true)">{{subchild.id}} &nbsp; {{subchild.title}}</a>
            <a class="menu-item" *ngIf="subchild.event" (click)="callFunction(subchild.event, subchild)">{{subchild.title}}</a>
          </td>
        </tr>
      </table>
    </td>
    <td><ui-switch class="switchery" switchColor="white" color="rgb(55, 188, 155)" name="{{'item-' + subchild.id + '-name'}}" [(ngModel)]="subchild.isChecked" (ngModelChange)="enableDisableMenuOption($event, subchild)"></ui-switch></td>
  </tr>
</table>

组件TS代码

import { Component, OnInit, Inject, AfterViewInit } from '@angular/core';
import { MenuConfigurationService } from "./menu-configuration.service"
import { DOCUMENT } from '@angular/common';

@Component({
  selector: 'app-menu-configuration',
  templateUrl: './menu-configuration.component.html',
  styleUrls: ['./menu-configuration.component.css']
})
export class MenuConfigurationComponent implements OnInit, AfterViewInit {
  child: any;
  constructor(
    @Inject(DOCUMENT) private document: Document,
    private menuConfigService: MenuConfigurationService) { }

  ngOnInit() {
    this.fetchAllMenuRoleWise();
  }

  saveMenuConfiguration(roleId: number, menu: any): void {
    this.menuConfigService.saveRoleConfiguration(roleId, menu)
      .subscribe({
        next: (data) => {
          this._menuSettingsConfig.vertical_menu = data;
          console.log(data);
        },
        error: (err) => {
          console.log(err);
        }
      });
  }
}

问题描述

UI加载完成或DOM就绪时,ui-switch会自动触发绑定的enableDisableMenuOption函数,这并非预期行为。尝试过用AfterViewInit设置布尔标志解决,但代码过于复杂,需要简洁方案。

简洁解决方案

方案1:使用(change)替代(ngModelChange)

ngx-ui-switch的(change)事件仅在用户手动切换开关时触发,初始化赋值不会触发该事件。修改HTML中的绑定:

<ui-switch class="switchery" switchColor="white" color="rgb(55, 188, 155)" 
           name="{{'item-' + subchild.id + '-name'}}" 
           [(ngModel)]="subchild.isChecked" 
           (change)="enableDisableMenuOption($event, subchild)">
</ui-switch>

(change)事件的参数是开关的当前状态(布尔值),和ngModelChange的参数一致,无需修改函数逻辑。

方案2:添加极简初始化过滤标志

如果必须使用ngModelChange,可以在组件中添加一个简单的标志过滤初始化触发:

  1. 在组件中添加属性并初始化:
private isInitialized = false;

ngAfterViewInit() {
  setTimeout(() => {
    this.isInitialized = true;
  });
}
  1. 修改enableDisableMenuOption函数:
enableDisableMenuOption(event: boolean, subchild: any) {
  if (!this.isInitialized) return;
  // 原函数逻辑代码
}

利用setTimeout确保Angular完成所有初始化绑定后再启用事件处理,逻辑简洁无冗余。

方案3:延迟渲染开关组件

通过*ngIf延迟ui-switch的渲染,直到初始化完成:

<td>
  <ui-switch *ngIf="isInitialized" class="switchery" switchColor="white" color="rgb(55, 188, 155)" 
             name="{{'item-' + subchild.id + '-name'}}" 
             [(ngModel)]="subchild.isChecked" 
             (ngModelChange)="enableDisableMenuOption($event, subchild)">
  </ui-switch>
</td>

同时在组件ngAfterViewInit中设置isInitialized = true,确保开关在初始化完成后才渲染,从根源避免初始化时的事件触发。


内容的提问来源于stack exchange,提问作者Dnyaneshwar Jadhav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 19:47:20