Angular ContentChildren 获取指令输入和 TemplateRef
Angular ContentChildren get directive Inputs and TemplateRef
我正在尝试为 ng-template
和 input
参数获取 TemplateRef
。
app.component.html:
<my-parent>
<ng-template my-directive title="Title1" let-dataItem="dataItem">
<div>{{dataItem|json}}</div>
</ng-template>
</my-parent>
问题是我只能得到TemplateRef
(标题未定义):
my-parent.html:
<div *ngFor="let detail of details" [title]="detail.title"> //!!! detail.title is undefined
<ng-container *ngTemplateOutlet="detail;context:{dataItem: dataItem}"></ng-container>
</div>
my-parent.ts
@ContentChildren(MyDirective, { read: TemplateRef }) details: QueryList<MyDirective>;
或者我可以获取输入参数:
my-parent.ts
@ContentChildren(MyDirective) details: QueryList<MyDirective>;
//in html detail.title is defined, but detail is not template and I get exception in line
<ng-container *ngTemplateOutlet="detail;context:{dataItem: dataItem}"></ng-container>
异常:
TypeError: templateRef.createEmbeddedView is not a function
我想我需要这个版本的 ContentChildren:
@ContentChildren(MyDirective, { read: TemplateRef }) details: QueryList<MyDirective>;
但是我怎样才能得到 MyDirective
输入参数(在这种情况下是 title
)?
我知道我可以同时使用:
@ContentChildren(MyDirective, { read: TemplateRef }) detailsRefs: QueryList<MyDirective>;
@ContentChildren(MyDirective) detailsInputs: QueryList<MyDirective>;
然后合并到新数组中:
public ngAfterViewInit(): void
{
const refs = this.detailsRefs.toArray();
const inputs = this.detailsInputs.toArray();
for (let i = 0; i < inputs.length; i++)
this.details.push({templateRef: refs[i], inputs: inputs[i]});
}
但肯定有更好的方法。
您可以通过 my-directive
中的输入读取 title
,然后从那里读取它,为此您需要删除 {read: TemplateRef}
:
@ContentChildren(MyDirective) details: QueryList<MyDirective>;
...
detail.title
据我所知,对于结构指令,输入需要以选择器为前缀。
@Directive({ selector: 'myDirective', ...})
class MyDirective {
@Input() myDirectiveTitle:string;
}
并像
一样使用它
<ng-template myDirective title="Title1" let-dataItem="dataItem">
并使用
阅读标题
detail.myDirectiveTitle
另见 https://angular.io/guide/structural-directives
这个代码
@ContentChildren(MyDirective, { read: TemplateRef }) details: QueryList<MyDirective>;
应该会导致错误,因为当您读取 TemplateRef
时,detail
应该是 QueryList<TemplateRef>
.
类型
可以用DI来完成:
@Directive({
selector: '[my-directive]'
})
export class MyDirective {
@Input() title: string;
constructor(public templateRef: TemplateRef<any>) {}
}
现在应该很容易理解我们可以利用前面的指令,例如:
parent.component.ts
@ContentChildren(MyDirective) details: QueryList<MyDirective>;
parent.component.html
<ng-container *ngTemplateOutlet="detail.templateRef
^^^^^^^^^^^^^
我正在尝试为 ng-template
和 input
参数获取 TemplateRef
。
app.component.html:
<my-parent>
<ng-template my-directive title="Title1" let-dataItem="dataItem">
<div>{{dataItem|json}}</div>
</ng-template>
</my-parent>
问题是我只能得到TemplateRef
(标题未定义):
my-parent.html:
<div *ngFor="let detail of details" [title]="detail.title"> //!!! detail.title is undefined
<ng-container *ngTemplateOutlet="detail;context:{dataItem: dataItem}"></ng-container>
</div>
my-parent.ts
@ContentChildren(MyDirective, { read: TemplateRef }) details: QueryList<MyDirective>;
或者我可以获取输入参数:
my-parent.ts
@ContentChildren(MyDirective) details: QueryList<MyDirective>;
//in html detail.title is defined, but detail is not template and I get exception in line
<ng-container *ngTemplateOutlet="detail;context:{dataItem: dataItem}"></ng-container>
异常:
TypeError: templateRef.createEmbeddedView is not a function
我想我需要这个版本的 ContentChildren:
@ContentChildren(MyDirective, { read: TemplateRef }) details: QueryList<MyDirective>;
但是我怎样才能得到 MyDirective
输入参数(在这种情况下是 title
)?
我知道我可以同时使用:
@ContentChildren(MyDirective, { read: TemplateRef }) detailsRefs: QueryList<MyDirective>;
@ContentChildren(MyDirective) detailsInputs: QueryList<MyDirective>;
然后合并到新数组中:
public ngAfterViewInit(): void
{
const refs = this.detailsRefs.toArray();
const inputs = this.detailsInputs.toArray();
for (let i = 0; i < inputs.length; i++)
this.details.push({templateRef: refs[i], inputs: inputs[i]});
}
但肯定有更好的方法。
您可以通过 my-directive
中的输入读取 title
,然后从那里读取它,为此您需要删除 {read: TemplateRef}
:
@ContentChildren(MyDirective) details: QueryList<MyDirective>;
...
detail.title
据我所知,对于结构指令,输入需要以选择器为前缀。
@Directive({ selector: 'myDirective', ...})
class MyDirective {
@Input() myDirectiveTitle:string;
}
并像
一样使用它 <ng-template myDirective title="Title1" let-dataItem="dataItem">
并使用
阅读标题detail.myDirectiveTitle
另见 https://angular.io/guide/structural-directives
这个代码
@ContentChildren(MyDirective, { read: TemplateRef }) details: QueryList<MyDirective>;
应该会导致错误,因为当您读取 TemplateRef
时,detail
应该是 QueryList<TemplateRef>
.
可以用DI来完成:
@Directive({
selector: '[my-directive]'
})
export class MyDirective {
@Input() title: string;
constructor(public templateRef: TemplateRef<any>) {}
}
现在应该很容易理解我们可以利用前面的指令,例如:
parent.component.ts
@ContentChildren(MyDirective) details: QueryList<MyDirective>;
parent.component.html
<ng-container *ngTemplateOutlet="detail.templateRef
^^^^^^^^^^^^^