使用 ngFor 处理自定义指令 - Angular2
handle custom directive with ngFor - Angular2
昨天我试图解决其中一个 SO 问题,但在我的解决方案中遇到了问题。
在组件的模板中,我正在使用 ngFor 指令,其中我正在使用我的自定义 popover
指令。 仅通过指令,我想显示每个 ngFor 对象的隐藏内容。
一旦你检查 http://plnkr.co/edit/X4U8ofJ5rgmE1YQ7fTAG?p=preview 你就会意识到我的问题。
在指令中使用的 mouseenter
事件我想显示适当的 ngFor
对象的内容。
directive.ts
import {Input,Component,Output,EventEmitter,Input,Directive,Hostbinding} from 'angular2/core';
import {Component, Input, OnInit, OnChanges, ChangeDetectionStrategy, ElementRef} from 'angular2/core';
@Directive({
selector: '.tower-details',
host:{
'(mouseenter)':'show($event)',
'(mouseout)':'hide()'
}
})
export class popover{
@Input() value: string;
@Output() valueChange=new EventEmitter();
ngOnChanges(...args:any[]){
//console.log(args[0].value);
}
show(val)
{
console.log(val.target);
this.valueChange.emit(true);
}
hide()
{
console.log('hide');
this.valueChange.emit(false);
}
}
app.ts
template: `
<div *ngFor="#p of popovers;#index=index">
<div class="tower-details" [(value)]="show" style="display: block;border:1px solid green;background-color:orange" >
Hover Me ! {{index}}
<div *ngIf="show">
<div class="popover top" style="display: block;border:1px solid green">
<h3 class="popover-title">{{p.title}}</h3>
<div class="popover-content">pop up content</div>
</div>
</div>
</div>
<br>
<br>
</div>
`
我猜你想要类似的东西
@Component({
selector: 'my-app',
providers: [],
template: `
<div *ngFor="let p of popovers;let index=index">
<div class="tower-details" [(value)]="show[p.title]" style="display: block;border:1px solid green;background-color:orange" >
Hover Me ! {{index}}
<div *ngIf="show[p.title]">
<div class="popover top" style="display: block;border:1px solid green">
<h3 class="popover-title">{{p.title}}</h3>
<div class="popover-content">pop up content</div>
</div>
</div>
</div>
<br>
<br>
</div>
`,
directives: [popover]
})
export class App {
popovers=[{"title":"popover1"},{"title":"popover2"},{"name":"title"}]
show={'popover1': false, 'popover2': false, 'title': false};
}
每个项目的状态需要单独存储。如果您对每个使用相同的值,则它们 show/hide 同步。
因为您在 [(value)]="show"
上使用双向绑定,每个项目的值将传播到 App
并返回到每个 tower-details
.
更新
您可以导出如下指令:
@Directive({
selector: '.tower-details',
host:{
'(mouseenter)':'show($event)',
'(mouseout)':'hide()'
},
exportAs: 'tower'
})
export class popover{
然后你可以创建一个模板变量来引用指令中的值
<div class="tower-details" #tower="tower" style="display: block;border:1px solid green;background-color:orange" >
Hover Me ! {{index}} - {{tower.value}}
<div *ngIf="tower.value">
您还需要在指令中设置 value
而不是仅仅发出一个事件。事实上,不再需要发出事件,除非您想通过其他方式进行绑定。
show(val)
{
console.log(val.target);
this.value = true;
this.valueChange.emit(true);
}
hide()
{
console.log('hide');
this.value = false;
this.valueChange.emit(false);
}
其实你使用的show
变量是全局的。你应该使用类似的东西:
@Component({
selector: 'my-app',
providers: [],
template: `
<div *ngFor="#p of popovers;#index=index">
<div class="tower-details" (valueChange)="show[index]=$event" style="display: block;border:1px solid green;background-color:orange" >
Hover Me ! {{index}}
<div *ngIf="show[index]">
<div class="popover top" style="display: block;border:1px solid green">
<h3 class="popover-title">{{p.title}}</h3>
<div class="popover-content">pop up content</div>
</div>
</div>
</div>
<br>
<br>
</div>
{{show | json }}
`,
directives: [popover]
})
export class App {
popovers=[{"title":"popover1"},{"title":"popover2"}, {"name":"title"}]
show=[false,false,false];
}
看到这个 plunkr:http://plnkr.co/edit/pIgH4OdMIf7rj2NOw9b6?p=preview。
编辑
再想一想,你可以直接利用applied指令的状态来避免使用show
数组。
@Directive({
selector: '.tower-details',
host:{
'(mouseenter)':'show($event)',
'(mouseout)':'hide()'
},
exportAs: 'popover'
})
export class popover{
shoudShow: false;
show(val) {
this.shoudShow = true;
}
hide() {
this.shoudShow = false;
}
}
在组件中是这样的:
@Component({
selector: 'my-app',
template: `
<div *ngFor="#p of popovers;#index=index">
<div class="tower-details" #dir="popover" style="display: block;border:1px solid green;background-color:orange" >
Hover Me ! {{index}}
<div *ngIf="dir.shoudShow">
<div class="popover top" style="display: block;border:1px solid green">
<h3 class="popover-title">{{p.title}}</h3>
<div class="popover-content">pop up content</div>
</div>
</div>
</div>
<br>
<br>
</div>
`,
directives: [popover]
})
export class App {
popovers=[{"title":"popover1"},{"title":"popover2"}, {"name":"title"}]
}
看到这个新的 plunkr:http://plnkr.co/edit/4Ewx15fYgm8AgejWZmXl?p=preview。
昨天我试图解决其中一个 SO 问题,但在我的解决方案中遇到了问题。
在组件的模板中,我正在使用 ngFor 指令,其中我正在使用我的自定义 popover
指令。 仅通过指令,我想显示每个 ngFor 对象的隐藏内容。
一旦你检查 http://plnkr.co/edit/X4U8ofJ5rgmE1YQ7fTAG?p=preview 你就会意识到我的问题。
在指令中使用的 mouseenter
事件我想显示适当的 ngFor
对象的内容。
directive.ts
import {Input,Component,Output,EventEmitter,Input,Directive,Hostbinding} from 'angular2/core';
import {Component, Input, OnInit, OnChanges, ChangeDetectionStrategy, ElementRef} from 'angular2/core';
@Directive({
selector: '.tower-details',
host:{
'(mouseenter)':'show($event)',
'(mouseout)':'hide()'
}
})
export class popover{
@Input() value: string;
@Output() valueChange=new EventEmitter();
ngOnChanges(...args:any[]){
//console.log(args[0].value);
}
show(val)
{
console.log(val.target);
this.valueChange.emit(true);
}
hide()
{
console.log('hide');
this.valueChange.emit(false);
}
}
app.ts
template: `
<div *ngFor="#p of popovers;#index=index">
<div class="tower-details" [(value)]="show" style="display: block;border:1px solid green;background-color:orange" >
Hover Me ! {{index}}
<div *ngIf="show">
<div class="popover top" style="display: block;border:1px solid green">
<h3 class="popover-title">{{p.title}}</h3>
<div class="popover-content">pop up content</div>
</div>
</div>
</div>
<br>
<br>
</div>
`
我猜你想要类似的东西
@Component({
selector: 'my-app',
providers: [],
template: `
<div *ngFor="let p of popovers;let index=index">
<div class="tower-details" [(value)]="show[p.title]" style="display: block;border:1px solid green;background-color:orange" >
Hover Me ! {{index}}
<div *ngIf="show[p.title]">
<div class="popover top" style="display: block;border:1px solid green">
<h3 class="popover-title">{{p.title}}</h3>
<div class="popover-content">pop up content</div>
</div>
</div>
</div>
<br>
<br>
</div>
`,
directives: [popover]
})
export class App {
popovers=[{"title":"popover1"},{"title":"popover2"},{"name":"title"}]
show={'popover1': false, 'popover2': false, 'title': false};
}
每个项目的状态需要单独存储。如果您对每个使用相同的值,则它们 show/hide 同步。
因为您在 [(value)]="show"
上使用双向绑定,每个项目的值将传播到 App
并返回到每个 tower-details
.
更新
您可以导出如下指令:
@Directive({
selector: '.tower-details',
host:{
'(mouseenter)':'show($event)',
'(mouseout)':'hide()'
},
exportAs: 'tower'
})
export class popover{
然后你可以创建一个模板变量来引用指令中的值
<div class="tower-details" #tower="tower" style="display: block;border:1px solid green;background-color:orange" >
Hover Me ! {{index}} - {{tower.value}}
<div *ngIf="tower.value">
您还需要在指令中设置 value
而不是仅仅发出一个事件。事实上,不再需要发出事件,除非您想通过其他方式进行绑定。
show(val)
{
console.log(val.target);
this.value = true;
this.valueChange.emit(true);
}
hide()
{
console.log('hide');
this.value = false;
this.valueChange.emit(false);
}
其实你使用的show
变量是全局的。你应该使用类似的东西:
@Component({
selector: 'my-app',
providers: [],
template: `
<div *ngFor="#p of popovers;#index=index">
<div class="tower-details" (valueChange)="show[index]=$event" style="display: block;border:1px solid green;background-color:orange" >
Hover Me ! {{index}}
<div *ngIf="show[index]">
<div class="popover top" style="display: block;border:1px solid green">
<h3 class="popover-title">{{p.title}}</h3>
<div class="popover-content">pop up content</div>
</div>
</div>
</div>
<br>
<br>
</div>
{{show | json }}
`,
directives: [popover]
})
export class App {
popovers=[{"title":"popover1"},{"title":"popover2"}, {"name":"title"}]
show=[false,false,false];
}
看到这个 plunkr:http://plnkr.co/edit/pIgH4OdMIf7rj2NOw9b6?p=preview。
编辑
再想一想,你可以直接利用applied指令的状态来避免使用show
数组。
@Directive({
selector: '.tower-details',
host:{
'(mouseenter)':'show($event)',
'(mouseout)':'hide()'
},
exportAs: 'popover'
})
export class popover{
shoudShow: false;
show(val) {
this.shoudShow = true;
}
hide() {
this.shoudShow = false;
}
}
在组件中是这样的:
@Component({
selector: 'my-app',
template: `
<div *ngFor="#p of popovers;#index=index">
<div class="tower-details" #dir="popover" style="display: block;border:1px solid green;background-color:orange" >
Hover Me ! {{index}}
<div *ngIf="dir.shoudShow">
<div class="popover top" style="display: block;border:1px solid green">
<h3 class="popover-title">{{p.title}}</h3>
<div class="popover-content">pop up content</div>
</div>
</div>
</div>
<br>
<br>
</div>
`,
directives: [popover]
})
export class App {
popovers=[{"title":"popover1"},{"title":"popover2"}, {"name":"title"}]
}
看到这个新的 plunkr:http://plnkr.co/edit/4Ewx15fYgm8AgejWZmXl?p=preview。