typescript 在 Angular 2 中的模板中进行类型转换
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45964576/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Type casting within a template in Angular 2
提问by Plog
I'm working on an Angular project (Angular 4.0.0) and I'm having trouble binding a property of an abstract class to ngModel because I first need to cast it as the concrete class it actually is in order to access the property.
我正在处理一个 Angular 项目(Angular 4.0.0),但我在将抽象类的属性绑定到 ngModel 时遇到了问题,因为我首先需要将它转换为它实际所在的具体类,以便访问该属性。
i.e. I have an AbstractEvent class this has a a concrete implementation Event which has a boolean property 'acknowledged' which I need a two way binding via ngModel to set with a checkbox.
即我有一个 AbstractEvent 类,它有一个具体的实现事件,它有一个布尔属性“已确认”,我需要通过 ngModel 进行双向绑定以使用复选框进行设置。
I currently have this element in my DOM:
我目前在我的 DOM 中有这个元素:
<input type="checkbox" *ngIf="event.end" [(ngModel)]="(event as Event).acknowledged"
[disabled]="(event as Event).acknowledged">
Unfortunately this is throwing the following error:
不幸的是,这引发了以下错误:
Uncaught Error: Template parse errors: Parser Error: Missing expected ) at column 8 in [(event as Event).acknowledged]
未捕获的错误:模板解析错误:解析器错误:在 [(event as Event).acknowledged] 的第 8 列中缺少预期
Googling around seemed to suggest this might be because using 'as' is not supported when using it inside a template? Although I'm not certain about this.
谷歌搜索似乎表明这可能是因为在模板中使用它时不支持使用“as”?虽然我不确定这一点。
I also can't work out how to just write a function for it in my typescript file driving the template because this would break the two way binding on ngModel that I require.
我也无法弄清楚如何在驱动模板的打字稿文件中为其编写函数,因为这会破坏我需要的 ngModel 上的双向绑定。
If anyone has any way to get around this or perform type casting in angular templates correctly I would be very appreciative!
如果有人有办法解决这个问题或在角度模板中正确执行类型转换,我将非常感激!
采纳答案by Qortex
As mentioned, using a barebone method call will have performance impact.
如前所述,使用准系统方法调用会对性能产生影响。
A better approach is to use a pipe, and you have best of both worlds. Just define a Cast pipe:
更好的方法是使用管道,您可以两全其美。只需定义一个 Cast 管道:
@Pipe({
name: 'cast',
pure: true
})
export class CastPipe implements PipeTransform {
constructor() {
}
transform(value: any, args?: any): Event {
return value;
}
}
and then in your template, use event | cast
when you need the cast.
然后在您的模板中,event | cast
在需要演员时使用。
That way, change detection stays efficient, and typing is safe (given the requested type change is sound of course).
这样,更改检测保持高效,并且输入是安全的(当然,所请求的类型更改是合理的)。
Unfortunately, I don't see a way to have this generic because of the name
attribute, so you'd have to define a new pipe for each type.
不幸的是,由于name
属性的原因,我没有看到具有这种通用性的方法,因此您必须为每种类型定义一个新管道。
回答by Günter Z?chbauer
That's not possible because Event
can't be referenced from within the template.
这是不可能的,因为Event
不能从模板中引用。
(as
is also not supported in template binding expressions)
You need to make it available first:
(as
在模板绑定表达式中也不支持)
您需要先使其可用:
class MyComponent {
EventType = Event;
then this should work
[(ngModel)]="(event as EventType).acknowledged"
class MyComponent {
EventType = Event;
那么这应该工作
[(ngModel)]="(event as EventType).acknowledged"
update
更新
class MyComponent {
asEvent(val) : Event { return val; }
then use it as
然后将其用作
[(ngModel)]="asEvent(event).acknowledged"
回答by Muhammet Can TONBUL
If you don't care about type control.
如果你不关心类型控制。
In Angular 9,
在 Angular 9 中,
[(ngModel)]="$any(event).acknowledged"
https://angular.io/guide/template-typecheck#disabling-type-checking-using-any
https://angular.io/guide/template-typecheck#disabling-type-checking-using-any