在Angular 2中的模板内键入铸件
我正在从事Angular项目(Angular 4.0.0),在将抽象类的属性绑定到ngModel时遇到问题,因为我首先需要将其转换为实际的具体类,以便访问该属性 i、 我有一个AbstractEvent类,这是一个具体的实现事件,它有一个布尔属性'acknowledged',我需要通过ngModel的双向绑定来设置一个复选框 我当前在DOM中有以下元素:在Angular 2中的模板内键入铸件,angular,typescript,Angular,Typescript,我正在从事Angular项目(Angular 4.0.0),在将抽象类的属性绑定到ngModel时遇到问题,因为我首先需要将其转换为实际的具体类,以便访问该属性 i、 我有一个AbstractEvent类,这是一个具体的实现事件,它有一个布尔属性'acknowledged',我需要通过ngModel的双向绑定来设置一个复选框 我当前在DOM中有以下元素: <input type="checkbox" *ngIf="event.end" [(ngModel)]="(event as Even
<input type="checkbox" *ngIf="event.end" [(ngModel)]="(event as Event).acknowledged"
[disabled]="(event as Event).acknowledged">
不幸的是,这会引发以下错误:
未捕获错误:模板分析错误:
分析程序错误:[(事件为事件)。已确认]
谷歌搜索似乎表明这可能是因为在模板中使用“as”时不支持使用它?虽然我对此不确定
我也不知道如何在驱动模板的typescript文件中为它编写函数,因为这会破坏我需要的ngModel上的双向绑定
如果有人有任何方法可以绕过这一点,或执行正确的角度模板类型铸造我会非常感激 这是不可能的,因为无法从模板中引用
事件
(as
在模板绑定表达式中也不受支持)
您需要首先使其可用:
class MyComponent {
EventType = Event;
那么这就行了
[(ngModel)]="(event as EventType).acknowledged"
更新
class MyComponent {
asEvent(val) : Event { return val; }
然后用它作为
[(ngModel)]="asEvent(event).acknowledged"
如前所述,使用基本方法调用将对性能产生影响
更好的方法是使用管道,这两个方面你都能做到最好。只需定义一个铸管:
@Pipe({
name: 'cast',
pure: true
})
export class CastPipe implements PipeTransform {
transform(value: any, args?: any): Event {
return value;
}
}
然后在您的模板中,需要时使用event | cast
这样,更改检测保持高效,并且键入是安全的(考虑到请求的类型更改是合理的)
不幸的是,由于name
属性的原因,我看不到一种方法来使用这个泛型,因此您必须为每种类型定义一个新管道。如果您不关心类型控制
角度8及更高版本
[(ngModel)]="$any(event).acknowledged"
如果使用类(而不是接口!),则可以传递类以从中提取类型
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'as',
pure: true,
})
export class AsPipe implements PipeTransform {
transform<T>(value: any, clss: new (...args: any[]) => T): T {
return value as T;
}
}
{{(行| as:MyClass.prop}}
这将不适用于接口,因为接口无法传递到模板中(在编写时)
要使用接口,您可能可以将其包装到类中:
class MyClass implements Partial<MyInterface> {}
类MyClass实现部分{}
使用Angular 11.1和最新的常春藤语言服务进行测试。感谢您的快速回复,但我似乎仍然收到了相同的错误:[(事件类型为EventType)。确认]“我更新了我的答案。这可能会对性能产生显著影响,因为绑定在模板中的函数经常被调用。如果没有必要,我会尽量避免使用它。你在没有施法的情况下会出现错误吗?非常感谢你的努力。是的,我不太担心表现。目前正在进行一项由我的一位同事编写的原型项目。在未来,我可能会尽量避免这种需要铸造的设计。再次感谢。请参阅下面我的答案,了解有关管道的解决方案,以避免负面性能影响。请记住,更改检测将导致多次调用转换函数,是否有其他方法可以实现相同的效果,而无需在模板中直接使用函数?我总是被告知尽可能避免这种情况。您可以将其用于类,看到非常好的解决方案,确实,感谢Doesn在我的情况下似乎不起作用,它说标识符“a”未定义T'不包含此类成员
在启用“strictTemplates”的情况下在Angular 12中工作。
<td mat-cell *matCellDef="let row">
{{ (row | as : MyClass).prop }}
</td>
class MyClass implements Partial<MyInterface> {}