在Angular 2中使用ngForTemplate时绑定事件

前端之家收集整理的这篇文章主要介绍了在Angular 2中使用ngForTemplate时绑定事件前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
假设我有这个简单的列表渲染组件:
  1. import {Input,Component } from 'angular2/core'
  2.  
  3. @Component({
  4. selector: 'my-list',template: `
  5. <div *ngFor='#item of items' (click)='onItemClicked(item)'>
  6. {{item}}
  7. </div>
  8. `
  9. })
  10. class MyList {
  11. @Input() items: string[];
  12.  
  13. onItemClicked(item) { console.log('Item clicked:',item); }
  14. }

我这样用:

  1. <my-list [items]='myAppsItems'></my-list>

到现在为止还挺好.

接下来,我决定我希望用户能够为渲染的项目提供自己的模板,因此我更改了组件

  1. @Component({
  2. selector: 'my-list',template: `
  3. <template ngFor [ngForOf]="items" [ngForTemplate]="userItemTemplate" (click)='onItemClicked(item)'>
  4. </template>
  5. `
  6. })
  7. class MyList {
  8. @Input() items: string[];
  9. @ContentChild(TemplateRef) userItemTemplate: TemplateRef;
  10.  
  11. onItemClicked(item) { console.log('Item clicked:',item); }
  12. }

并使用它:

  1. <my-list [items]='items'>
  2. <template #item>
  3. <h1>item: {{item}}</h1>
  4. </template>
  5. </my-list>

这只有我不绑定任何事件处理程序到列表项(plunker).如果我尝试绑定到点击事件,就像我在组件的第一个版本中一样,Angular会抛出以下异常:

  1. "Event binding click not emitted by any directive on an embedded template"

这是一个plunker showing that.您可以删除点击绑定,它将工作.

我该如何解决?我只想让用户能够指定一个下级项目的模板,我将通过ngFor进行迭代,但是我需要能够将处理程序绑定到这些项目.

项目模板在应用程序上下文中定义,但不清楚如何将其附加到我的列表组件上下文中.我有创建包装指令来处理模板及其变量,指令被包装到div中以捕获事件.它可以像这样使用:
  1. @Directive({
  2. selector: '[ngWrapper]'
  3. })
  4. export class NgWrapper
  5. {
  6. @Input()
  7. private item:any;
  8.  
  9. private _viewContainer:ViewContainerRef;
  10.  
  11. constructor(_viewContainer:ViewContainerRef)
  12. {
  13. this._viewContainer = _viewContainer;
  14. }
  15.  
  16. @Input()
  17. public set ngWrapper(templateRef:TemplateRef)
  18. {
  19. var embeddedViewRef = this._viewContainer.createEmbeddedView(templateRef);
  20. embeddedViewRef.setLocal('item',this.item)
  21. }
  22. }
  1. @Component({
  2. selector: 'my-list',directives: [NgWrapper],template: `
  3. <template ngFor #item [ngForOf]="items">
  4. <div (click)="onItemClicked(item)">
  5. <template [ngWrapper]="userItemTemplate" [item]="item"></template>
  6. </div>
  7. </template>
  8. `
  9. })
  10. class MyList {
  11. @Input() items: string[];
  12. @ContentChild(TemplateRef) userItemTemplate: TemplateRef;
  13. userItemTemplate1: TemplateRef;
  14.  
  15. onItemClicked(item) {
  16. console.log('Item click:',item);
  17. }
  18.  
  19. ngAfterViewInit(){
  20. this.userItemTemplate;
  21. }
  22. }
  1. @Component({
  2. selector: 'my-app',directives: [MyList],template: `
  3. <my-list [items]='items'>
  4. <template #item="item">
  5. <h1>item: {{item}}</h1>
  6. </template>
  7. </my-list>
  8. `
  9. })
  10. export class App {
  11. items = ['this','is','a','test']
  12.  
  13. onItemClicked(item) {
  14. console.log('Item click:',item);
  15. }
  16. }

解决方案不是很好,但几乎很好,请检查plunkr.

猜你在找的Angularjs相关文章