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
相关产品推荐
相关产品推荐

