加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-17 07:33:27 所属栏目:安全 来源:网络整理
导读:假设我有这个简单的列表渲染组件: import {Input,Component } from 'angular2/core'@Component({ selector: 'my-list',template: ` div *ngFor='#item of items' (click)='onItemClicked(item)' {{item}} /div `})class MyList { @Input() items: string[];
假设我有这个简单的列表渲染组件:
import {Input,Component } from 'angular2/core'

@Component({
  selector: 'my-list',template: `
      <div *ngFor='#item of items' (click)='onItemClicked(item)'>
          {{item}}
      </div>
  `
})
class MyList {
    @Input() items: string[];

    onItemClicked(item) { console.log('Item clicked:',item); }
}

我这样用:

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

到现在为止还挺好.

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

@Component({
  selector: 'my-list',template: `
      <template ngFor [ngForOf]="items" [ngForTemplate]="userItemTemplate" (click)='onItemClicked(item)'>
      </template>
  `
})
class MyList {
    @Input() items: string[];
    @ContentChild(TemplateRef) userItemTemplate: TemplateRef;

    onItemClicked(item) { console.log('Item clicked:',item); }
}

并使用它:

<my-list [items]='items'>
   <template #item>
        <h1>item: {{item}}</h1>
   </template>
</my-list>

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

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

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

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

项目模板在应用程序上下文中定义,但不清楚如何将其附加到我的列表组件上下文中.我有创建包装指令来处理模板及其变量,指令被包装到div中以捕获事件.它可以像这样使用:
@Directive({
    selector: '[ngWrapper]'
})
export class NgWrapper
{
    @Input()
    private item:any;

    private _viewContainer:ViewContainerRef;

    constructor(_viewContainer:ViewContainerRef)
    {
        this._viewContainer = _viewContainer;
    }

    @Input()
    public set ngWrapper(templateRef:TemplateRef)
    {
        var embeddedViewRef = this._viewContainer.createEmbeddedView(templateRef);
        embeddedViewRef.setLocal('item',this.item)
    }
}
@Component({
  selector: 'my-list',directives: [NgWrapper],template: `
      <template ngFor #item [ngForOf]="items">
      <div (click)="onItemClicked(item)">
      <template [ngWrapper]="userItemTemplate" [item]="item"></template>
      </div>
      </template>
  `
})
class MyList {
    @Input() items: string[];
    @ContentChild(TemplateRef) userItemTemplate: TemplateRef;
    userItemTemplate1: TemplateRef;

    onItemClicked(item) {
        console.log('Item click:',item);
    }

    ngAfterViewInit(){
      this.userItemTemplate;
    }
}
@Component({
  selector: 'my-app',directives: [MyList],template: `
    <my-list [items]='items'>
      <template #item="item">
            <h1>item: {{item}}</h1>
       </template>
    </my-list>
  `
})
export class App {
  items = ['this','is','a','test']

      onItemClicked(item) {
        console.log('Item click:',item);
    }
}

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读