使用ngFor处理自定义指令 - Angular2

时间:2016-04-12 08:42:32

标签: angular angular2-directives

昨天我试图在我的解决方案中使用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>
  `

2 个答案:

答案 0 :(得分:1)

我想你想要像

这样的东西
-O3

每个项目的状态需要单独存储。如果为每个使用相同的值,它们将显示/隐藏同步。

由于您在-O1上使用双向绑定,因此每个项目的值将传播到@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}; } 并返回到每个[(value)]="show"

Plunker example

<强>更新

您可以导出如下指令:

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">

Plunker example

答案 1 :(得分:1)

实际上,您使用的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

修改

再次思考之后,您可以直接利用应用指令的状态来避免使用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