用另一个结构指令包装 Angular ngFor 指令
Wrap Angular ngFor directive with another structural directive
我的 AppComponent 模板(在 AppModule 中引导)是
<div *myDir="let item of mySource">
My Directive #{{item}}
</div>
其中 mySource
是具有 list
属性
的对象
mySource = { list: [1, 2, 3, 4, 5] };
因此,将 myDir
替换为 ngFor
(*ngFor="let item of mySource.list"
) 会得到
My Directive #1
My Directive #2
My Directive #3
My Directive #4
My Directive #5
我正在尝试实现 myDir
与 myComponent
的配对,以在 ngFor
Angular 核心指令上提供模板化包装器,以便能够传递 mySource
(而不是 mySource.list
)并获得相同的结果。当然,最终目标要复杂得多,但我需要用最少的例子来解决这个任务……做了什么?
my.directive.ts
import { MyComponent } from './my.component';
@Directive({ selector: '[myDir][myDirOf]' })
export class MyDirective {
private source;
constructor(/* ... */) { }
@Input() set myDirOf(source) {
this.source = source;
}
ngOnInit() {
// dynamic wrapping with MyComponent
const templateView = this.templateRef.createEmbeddedView({});
const compFactory = this.resolver.resolveComponentFactory(MyComponent);
const componentRef = this.viewContainer.createComponent(compFactory, null, this.viewContainer.injector, [templateView.rootNodes]);
// passing MyDir params to Mycomponent's instance
componentRef.instance.source = this.source;
componentRef.instance.template = this.templateRef;
}
}
my.component.ts
@Component({
selector: 'app-my',
template: `
<div *ngFor="let item of source.list">
<ng-template
[ngTemplateOutlet]="template"
[ngTemplateOutletContext]="{
item: item
}">
</ng-template>
</div>`
})
export class MyComponent implements OnInit {
source;
template;
constructor() { }
}
问题是我无法将 item
传递回主机组件的模板,所以目前我只得到 5 行包含 "My Directive #" 而 {{item}}
不不工作。 MyComponent 的 ng-template
似乎有问题。它接受 template
但不会传递 item
.
我根据我目前的情况创建了一个可编辑的 DEMO。另外,这是我需要的简单图表:
使用$implicit
将数据传递给item
my.component.html
<div *ngFor="let item of source.list">
<ng-template
[ngTemplateOutlet]="template"
[ngTemplateOutletContext]="{
$implicit: item
}">
</ng-template>
</div>
您的模板
<div *myDir="let item of mySource">
My Directive #{{item}}
</div>
等同于
<ng-template myDir let-item [myDirOf]="mySource">
<div>
My Directive #{{item}}
</div>
</ng-template>
但是如果模板变量 (let-item) 没有值那么它默认需要 $implicit
<ng-template myDir let-item="$implicit" [myDirOf]="mySource">
<div>
My Directive #{{item}}
</div>
</ng-template>
另见
我的 AppComponent 模板(在 AppModule 中引导)是
<div *myDir="let item of mySource">
My Directive #{{item}}
</div>
其中 mySource
是具有 list
属性
mySource = { list: [1, 2, 3, 4, 5] };
因此,将 myDir
替换为 ngFor
(*ngFor="let item of mySource.list"
) 会得到
My Directive #1
My Directive #2
My Directive #3
My Directive #4
My Directive #5
我正在尝试实现 myDir
与 myComponent
的配对,以在 ngFor
Angular 核心指令上提供模板化包装器,以便能够传递 mySource
(而不是 mySource.list
)并获得相同的结果。当然,最终目标要复杂得多,但我需要用最少的例子来解决这个任务……做了什么?
my.directive.ts
import { MyComponent } from './my.component';
@Directive({ selector: '[myDir][myDirOf]' })
export class MyDirective {
private source;
constructor(/* ... */) { }
@Input() set myDirOf(source) {
this.source = source;
}
ngOnInit() {
// dynamic wrapping with MyComponent
const templateView = this.templateRef.createEmbeddedView({});
const compFactory = this.resolver.resolveComponentFactory(MyComponent);
const componentRef = this.viewContainer.createComponent(compFactory, null, this.viewContainer.injector, [templateView.rootNodes]);
// passing MyDir params to Mycomponent's instance
componentRef.instance.source = this.source;
componentRef.instance.template = this.templateRef;
}
}
my.component.ts
@Component({
selector: 'app-my',
template: `
<div *ngFor="let item of source.list">
<ng-template
[ngTemplateOutlet]="template"
[ngTemplateOutletContext]="{
item: item
}">
</ng-template>
</div>`
})
export class MyComponent implements OnInit {
source;
template;
constructor() { }
}
问题是我无法将 item
传递回主机组件的模板,所以目前我只得到 5 行包含 "My Directive #" 而 {{item}}
不不工作。 MyComponent 的 ng-template
似乎有问题。它接受 template
但不会传递 item
.
我根据我目前的情况创建了一个可编辑的 DEMO。另外,这是我需要的简单图表:
使用$implicit
将数据传递给item
my.component.html
<div *ngFor="let item of source.list">
<ng-template
[ngTemplateOutlet]="template"
[ngTemplateOutletContext]="{
$implicit: item
}">
</ng-template>
</div>
您的模板
<div *myDir="let item of mySource">
My Directive #{{item}}
</div>
等同于
<ng-template myDir let-item [myDirOf]="mySource">
<div>
My Directive #{{item}}
</div>
</ng-template>
但是如果模板变量 (let-item) 没有值那么它默认需要 $implicit
<ng-template myDir let-item="$implicit" [myDirOf]="mySource">
<div>
My Directive #{{item}}
</div>
</ng-template>
另见