在Angular 2中的模板内键入铸件

在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

我正在从事Angular项目(Angular 4.0.0),在将抽象类的属性绑定到ngModel时遇到问题,因为我首先需要将其转换为实际的具体类,以便访问该属性

i、 我有一个AbstractEvent类,这是一个具体的实现事件,它有一个布尔属性'acknowledged',我需要通过ngModel的双向绑定来设置一个复选框

我当前在DOM中有以下元素:

<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> {}