[英]Angular 2 Custom Structural Directive binding using template input variable is not working
I have created a custom structural directive similar to ngFor
. 我创建了一个类似于ngFor
的自定义结构指令。 When I try to use it using <template>
element syntax, the binding inside the template is working but when I use * syntax, the binding is not working. 当我尝试使用<template>
元素语法使用它时, <template>
内的绑定有效,但是当我使用*语法时,该绑定不起作用。
<!-- working -->
<template edit [editOf]="values" let-val="val">
<table >
<span>This is using template syntax {{val}}</span>
</table>
</template>
<!-- not working -->
<table *edit="let val1 of values">
<span>This uses star syntax {{val1}}</span>
</table>
Here is the plnkr link for this issue. 这是此问题的plnkr链接 。
What am I doing wrong? 我究竟做错了什么?
Update: I think, now I understand what is going on. 更新:我想,现在我了解发生了什么。 The let-val
is incorrectly set to a property val
of object used for binding but I need the whole object. let-val
错误地设置为用于绑定的对象的属性val
,但是我需要整个对象。 So, the let-val
shouldn't be assigned with any value in the template and then I'll have to update the context.$implicit with the object used as binding source in the viewRef. 因此,不应在模板中为let-val
分配任何值,然后我必须更新context。$ implicit,并将该对象用作viewRef中的绑定源。
Working plnkr here. 在这里工作plnkr。
Thanks to @robisim74 感谢@ robisim74
Try this: 尝试这个:
import { ChangeDetectorRef,
Directive,
Input,
DoCheck,
IterableDiffer,
IterableDiffers,
TemplateRef,
ViewContainerRef,
EmbeddedViewRef} from "@angular/core";
@Directive({
"selector":"[edit][editOf]"
})
export class EditableTableDirective implements DoCheck {
private collection:any;
private differ:IterableDiffer;
private viewMap:Map<any,EmbeddedViewRef> = new Map<any,EmbeddedViewRef>();
constructor(
private changeDetector:ChangeDetectorRef,
private differs:IterableDiffers,
private template:TemplateRef,
private viewContainer:ViewContainerRef){
}
@Input() set editOf(coll:any){
this.collection = coll;
if (coll && !this.differ) {
this.differ = this.differs.find(coll).create(this.changeDetector);
}
}
ngDoCheck() {
if (this.differ) {
const changes = this.differ.diff(this.collection);
if (changes) {
changes.forEachAddedItem((change) => {
const view = this.viewContainer.createEmbeddedView(this.template, change.item);
view.context.$implicit = change.item;
this.viewMap.set(change.item, view);
});
changes.forEachRemovedItem((change) => {
const view = this.viewMap.get(change.item);
const viewIndex = this.viewContainer.indexOf(view);
this.viewContainer.remove(viewIndex);
this.viewMap.delete(change.item);
});
}
}
}
}
Then correct the template: 然后更正模板:
<table *edit="let item of values">
<span>This uses star syntax {{item.val}}</span>
</table>
I followed this article: http://teropa.info/blog/2016/03/06/writing-an-angular-2-template-directive.html 我关注了这篇文章: http : //teropa.info/blog/2016/03/06/writing-an-angular-2-template-directive.html
<tr *cpLoop="let cat of categories" (click)="selectCategory(cat)">
<td>{{cat.categoryId}}</td>
<td>{{cat.categoryName}}</td>
</tr>
<ng-template cpLoop let-cat [cpLoopOf]="categories" let-i="index">
<tr (click)="selectCategory(cat)">
<td>{{cat.categoryId}}</td>
<td>{{cat.categoryName}}</td>
</tr>
</ng-template>
@Input() set cpLoopOf(rows:any){
rows.forEach((row:any, index:any) => {
let viewRef = this.viewContainer.createEmbeddedView(this.template, row);
viewRef.context.$implicit =row;
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.