Binding events when using a ngForTemplate in Angular 2

前端 未结 2 1364
感情败类
感情败类 2020-12-01 09:33

Let\'s say I\'ve got this simple list rendering component:

import {Input, Component } from \'angular2/core\'

@Component({
  selector: \'my-list\',
  templat         


        
相关标签:
2条回答
  • 2020-12-01 10:14

    Item template is defined in App context, it is not clear how to attach it to my-list component context. I have create wrapper directive that handles template and its variables, directive is wrapped into div to capture events. It can be used like this:

    @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);
        }
    }
    

    The solution is not prerfect but nearly good, check plunkr.

    0 讨论(0)
  • 2020-12-01 10:31

    Been looking for an answer to this for a week now and I finally came up with a pretty decent solution. Instead of using ngForTemplate I would suggest using ngTemplateOutlet.

    It is already described pretty well here: angular2 feeding data back to `<template>` from `[ngTemplateOutlet]`

    The custom template for the list items is placed between the component tags:

    <my-list>
      <template let-item="item">
        Template for: <b>{{item.text}}</b> ({{item.id}})
      </template>
    </my-list>
    

    And the component template:

    <ul>
      <li *ngFor="let item of listItems" (click)="pressed(item)">
        <template 
          [ngTemplateOutlet]="template" 
          [ngOutletContext]="{
            item: item
          }">
        </template>
      </li>
    </ul>
    

    I made an example here: https://plnkr.co/edit/4cf5BlVoqzZdUQASVQaC?p=preview

    0 讨论(0)
提交回复
热议问题