在Angular 2中的模板中键入cast

时间:2017-08-30 15:37:57

标签: angular typescript

我正在开发Angular项目(Angular 4.0.0),而且我无法将抽象类的属性绑定到ngModel,因为我首先需要将它作为实际的具体类进行转换为了进入该物业。

即。我有一个AbstractEvent类,它有一个具体的实现Event,它有一个布尔属性'确认'我需要通过ngModel双向绑定来设置复选框。

我目前在我的DOM中有这个元素:

<input type="checkbox" *ngIf="event.end" [(ngModel)]="(event as Event).acknowledged" 
                                          [disabled]="(event as Event).acknowledged">

不幸的是,这会引发以下错误:

  

未捕获错误:模板解析错误:   在[(作为事件的事件)中的第8列的分析器错误:缺少预期)。已确认]

谷歌搜索似乎表明这可能是因为使用&#39;作为&#39;在模板中使用它时不受支持?虽然我对此不确定。

我也无法解决如何在驱动模板的打字稿文件中为其编写函数,因为这会破坏我需要的ngModel上的双向绑定。

如果有人有办法绕过这个或正确地在角度模板中进行类型转换,我将非常感激!

4 个答案:

答案 0 :(得分:22)

这是不可能的,因为Event无法从模板中引用。

(模板绑定表达式中也不支持as) <击> 您需要先将其提供:

class MyComponent {
  EventType = Event;

然后这应该工作

[(ngModel)]="(event as EventType).acknowledged"

<击>

<强>更新

class MyComponent {
  asEvent(val) : Event { return val; }

然后将其用作

[(ngModel)]="asEvent(event).acknowledged"

答案 1 :(得分:12)

如果您使用类(不是接口!),您可以传递类以从中提取类型。

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

}

clss 参数未使用,但用于主要目标:从构造函数推断类型。

可以用作:

class Event {
  prop: string;
}

export class MyComponent {

  MyClass = MyClass; // export class as value, that is visible in the template

}
<td mat-cell *matCellDef="let row">
  {{ (row | as : MyClass).prop }}
</td>

这不适用于接口,因为接口无法传递到模板中(在编写时)。

要使用接口,你大概可以把它包装到类中:

class MyClass implements Partial<MyInterface> {}

使用 Angular 11.1 和最新的 Ivy 语言服务进行测试。

答案 2 :(得分:2)

如果您不关心类型控制。

在Angular 8中,

[(ngModel)]="$any(event).acknowledged"

答案 3 :(得分:1)

如前所述,使用准系统方法调用会影响性能。

更好的方法是使用管道,并且您可以两全其美。只需定义一个Cast管道即可:

@Pipe({
  name: 'cast',
  pure: true
})
export class CastPipe implements PipeTransform {

  constructor() {
  }

  transform(value: any, args?: any): Event {
    return value;
  }
}

,然后在模板中,在需要强制转换时使用event | cast

这样,更改检测将保持高效,并且键入是安全的(当然,所请求的类型更改是合理的)。

不幸的是,由于name属性的缘故,我看不到拥有此泛型的方法,因此您必须为每种类型定义一个新管道。