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

Angular 5中如何修改ng-template模板变量?

解决Angular ng-template中无法修改上下文变量的问题

这个问题我之前也碰到过,Angular的ng-template上下文变量(比如你这里的o)是只读的引用,直接在模板里赋值修改会触发Angular的保护机制,所以才会抛出Uncaught Error: Cannot assign to a reference or variable!这个错误。下面给你几个实用的解决方案:

方法一:用对象包装状态(最推荐)

把要传递的opened状态包装成一个对象,因为对象是引用类型,我们可以修改对象的属性而不是重新赋值变量本身,这样就能绕过Angular的只读限制。

修改后的代码如下:

<ng-template let-o="opened" [ngTemplateOutletContext]="{ opened: { value: d === 0 } }" [ngTemplateOutlet]="item" #item>
  <div class="columns table-header is-marginless">
    <button (click)="o.value = !o.value">+</button>
    <div [hidden]="!o.value">Toggle me on button click</div>
  </div>
</ng-template>

这里我们把opened的值放在了{ value: ... }对象里,点击按钮时修改的是o.value,而不是重新赋值o本身,完全符合Angular的规则。

方法二:将状态移到组件类中

如果这个开关状态需要和组件的其他逻辑交互,或者需要在多个地方复用,更建议把状态定义在组件的.ts文件里:

组件类代码:

import { Component } from '@angular/core';

@Component({
  // 组件元数据
})
export class YourComponent {
  d = 0;
  isOpened = this.d === 0; // 初始化状态

  toggleOpened() {
    this.isOpened = !this.isOpened;
  }
}

对应的模板代码:

<ng-template [ngTemplateOutlet]="item" #item>
  <div class="columns table-header is-marginless">
    <button (click)="toggleOpened()">+</button>
    <div [hidden]="!isOpened">Toggle me on button click</div>
  </div>
</ng-template>

这种方式更符合Angular的组件化思想,状态由组件统一管理,逻辑更清晰。

方法三:通过ViewChild维护上下文(适合特殊场景)

如果必须要在模板上下文中操作,可以通过ViewChild获取模板引用,在组件类中维护上下文对象:

组件类代码:

import { Component, ViewChild, TemplateRef } from '@angular/core';

@Component({
  // 组件元数据
})
export class YourComponent {
  d = 0;
  templateContext = { opened: this.d === 0 };

  @ViewChild('item') itemTemplate!: TemplateRef<any>;

  toggleOpened() {
    this.templateContext.opened = !this.templateContext.opened;
  }
}

模板代码:

<ng-template let-o="opened" [ngTemplateOutletContext]="templateContext" [ngTemplateOutlet]="item" #item>
  <div class="columns table-header is-marginless">
    <button (click)="toggleOpened()">+</button>
    <div [hidden]="!o">Toggle me on button click</div>
  </div>
</ng-template>

这种方式通过组件类来修改上下文对象,模板里的o会自动同步更新,但相对前两种方法来说更繁琐,只适合特殊场景使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:18:15