ssu*_*ski 8 typescript angular
父组件如何识别let-content其来源 类型ngTemplateOutletContext?现在{{content.type}}可以正常工作,但是IDE会说:
未解析的变量类型
如何输入为Video?
parent.component.ts:
export interface Video {
id: number;
duration: number;
type: string;
}
public videos: Video = [{id: 1, duration: 30, type: 'documentary'}];
Run Code Online (Sandbox Code Playgroud)
parent.component.html:
<ul>
<li *ngFor="let video of videos">
<tile [bodyTemplate]="tileTemplate" [content]="video"></app-card>
</li>
</ul>
<ng-template #tileTemplate let-content>
<h5 class="tile__type">{{content.type}}</h5>
</ng-template>
Run Code Online (Sandbox Code Playgroud)
tile.component.ts:
@Component({
selector: 'tile',
templateUrl: './tile.component.html',
styleUrls: ['./tile.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CardComponent {
@Input() tileTemplate: TemplateRef<any>;
@Input() content: Video;
}
Run Code Online (Sandbox Code Playgroud)
tile.component.html:
<div
...
<ng-container
[ngTemplateOutlet]="tileTemplate"
[ngTemplateOutletContext]="{ $implicit: content }">
</ng-container>
...
</div>
Run Code Online (Sandbox Code Playgroud)
Lor*_*ole 36
我创建了一个辅助指令来解决这个问题。
import { Directive, Input, TemplateRef } from '@angular/core';
@Directive({selector: 'ng-template[typedTemplate]'})
export class TypedTemplateDirective<TypeToken> {
// how you tell the directive what the type should be
@Input('typedTemplate')
typeToken: TypeToken;
// the directive gets the template from Angular
constructor(private contentTemplate: TemplateRef<TypeToken>) {
}
// this magic is how we tell Angular the context type for this directive, which then propagates down to the type of the template
static ngTemplateContextGuard<TypeToken>(dir: TypedTemplateDirective<TypeToken>, ctx: unknown): ctx is TypeToken{ return true; }
}
Run Code Online (Sandbox Code Playgroud)
像这样使用它
<!-- typedTemplate is the directive, typeToken is an object on our component -->
<ng-template #someTemplate [typedTemplate]="typeToken" let-param="param">
{{param}}
</ng-template>
Run Code Online (Sandbox Code Playgroud)
并且在组件中
// here we create typeToken. the value doesn't matter as it's never used, but the type of this variable defines the types of all template parameters.
typeToken: { param: string };
Run Code Online (Sandbox Code Playgroud)
有一个简单的解决方法可以让 IDE 运行并使用用户定义的类型保护来完成代码:
在您的类中创建一个函数,该函数将变量作为参数并返回相同的变量:
export class CardComponent {
...
public video = (item: Video) => item;
}
Run Code Online (Sandbox Code Playgroud)
现在只需使用函数将变量包装在模板中:
<h5 class="tile__type">{{video(content).type}}</h5>
Run Code Online (Sandbox Code Playgroud)
没有let-*变量的类型推断。所述let-上下文是微句法分析器折角的一部分,并且因为没有明确原点的IDE不能推断的类型。
https://gist.github.com/mhevery/d3530294cff2e4a1b3fe15ff75d08855
您可以尝试使用以下方法使IDE警告静音 $any()
https://angular.io/guide/template-syntax#the-any-type-cast-function
<ng-template #tileTemplate let-content>
<h5 class="tile__type">{{$any(content).type}}</h5>
</ng-template>
Run Code Online (Sandbox Code Playgroud)
您可以使用函数来强制类型推断
<ng-template #tileTemplate let-content>
<h5 class="tile__type">{{toVideo(content).type}}</h5>
</ng-template>
public toVideo(value: any): Video { return value as Video; }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1026 次 |
| 最近记录: |