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

Angular ng-bootstrap Tabs组件切换时表单内容不更新问题如何解决

问题根因

你的问题核心是两个标签页的表单控件绑定冲突:

  • 两个表单下的富文本编辑器都使用了formControlName="htmlContent",且未绑定独立的FormGroup实例,导致两个编辑器实际指向同一个表单控制对象,修改任意一个都会同步另一个的数据
  • ng-bootstrap的ngbNav默认会缓存已渲染的标签内容,没有额外配置的情况下不会主动销毁重建标签内的DOM,进一步加剧了数据串用的问题

你尝试用ng-container替换ng-template的操作不符合ngbNav的使用规范:ngbNavContent指令必须作用在ng-template上,由ngbNav内部动态渲染激活标签对应的模板内容,直接用ng-container会让所有标签内容直接输出到DOM,自然出现堆叠问题。

解决方案

步骤1:为两个表单分别创建独立的FormGroup

修改你的ts组件代码,引入响应式表单相关依赖,为每个表单声明独立的FormGroup:

import { Component, OnInit } from '@angular/core';
import { AngularEditorConfig } from '@kolkov/angular-editor';
import { NgbNavChangeEvent } from '@ng-bootstrap/ng-bootstrap';
// 新增导入响应式表单依赖
import { FormBuilder, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-tabs',
  templateUrl: './tabs.component.html',
  styleUrls: ['./tabs.component.css'],
})
export class TabsComponent implements OnInit {
  editorConfig: AngularEditorConfig = {
    editable: true,
    spellcheck: true,
    height: '500px',
    minHeight: '0',
    maxHeight: 'auto',
    width: 'auto',
    minWidth: '0',
    translate: 'yes',
    enableToolbar: true,
    showToolbar: true,
    placeholder: 'Enter text here...',
    defaultParagraphSeparator: '',
    defaultFontName: '',
    defaultFontSize: '',
    fonts: [
      { class: 'arial', name: 'Arial' },
      { class: 'times-new-roman', name: 'Times New Roman' },
      { class: 'calibri', name: 'Calibri' },
      { class: 'comic-sans-ms', name: 'Comic Sans MS' },
    ],
    customClasses: [
      {
        name: 'quote',
        class: 'quote',
      },
      {
        name: 'redText',
        class: 'redText',
      },
      {
        name: 'titleText',
        class: 'titleText',
        tag: 'h1',
      },
    ],
    uploadUrl: 'v1/image',
    uploadWithCredentials: false,
    sanitize: true,
    toolbarPosition: 'top',
    toolbarHiddenButtons: [['bold', 'italic'], ['fontSize']],
  };

  active: number;
  disabled = true;
  // 新增两个独立的FormGroup
  privacyForm: FormGroup;
  termsForm: FormGroup;

  // 注入FormBuilder
  constructor(private fb: FormBuilder) {}

  ngOnInit(): void {
    // 初始化两个表单
    this.privacyForm = this.fb.group({
      htmlContent: ['']
    });
    this.termsForm = this.fb.group({
      htmlContent: ['']
    });
    // 初始化默认激活第一个标签
    this.active = 1;
  }

  onNavChange(changeEvent: NgbNavChangeEvent) {
    if (changeEvent.nextId === 3) {
      changeEvent.preventDefault();
    }
    // 如果你需要切换标签时清空对应表单数据,可以取消注释以下代码
    // if (changeEvent.nextId === 1) {
    //   this.privacyForm.reset();
    // } else if (changeEvent.nextId === 2) {
    //   this.termsForm.reset();
    // }
  }

  toggleDisabled() {
    this.disabled = !this.disabled;
    if (this.disabled) {
      this.active = 1;
    }
  }
}

步骤2:修改HTML表单绑定

给每个form标签绑定对应的FormGroup实例,隔离两个表单的控制域:

<!-- 第一个标签页的表单 -->
<form [formGroup]="privacyForm">
  <br />
  <label>Heading (Privacy Policy)</label><br />
  <input type="text" />
  <br />
  <br />
  <label>Content</label>
  <angular-editor
    id="editor1"
    formControlName="htmlContent"
    [config]="editorConfig"
  ></angular-editor>
  <br />
  <button class="btn btn-danger">Save Changes</button>
</form>

<!-- 第二个标签页的表单 -->
<form [formGroup]="termsForm">
  <br />
  <label>Heading (T&C)</label><br />
  <input type="text" />
  <br />
  <br />
  <label>Content</label>
  <angular-editor
    id="editor2"
    formControlName="htmlContent"
    [config]="editorConfig"
  ></angular-editor>
  <br />
  <button class="btn btn-danger">Save Changes</button>
</form>

其余HTML代码保持原有写法即可,不需要修改ng-template的使用。

修改完成后两个表单的控件就完全隔离,切换标签时不会再出现数据串用的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 07:39:03