Angular2: replace host element with component's template

前端 未结 5 1705
别跟我提以往
别跟我提以往 2021-01-30 17:23

I\'m new to angular in general and to angular2 specifically. I\'m trying to write a container component, which should have child components in it.

相关标签:
5条回答
  • 2021-01-30 17:52

    New angular versions have really cool directive, which may be used also for your use case. Tadaa: NgComponentOutlet. Happy coding ;)

    Example:

    @Component({selector: 'hello-world', template: 'Hello World!'})
    class HelloWorld {
    }
    
    @Component({
      selector: 'ng-component-outlet-simple-example',
      template: `<ng-container *ngComponentOutlet="HelloWorld"></ng-container>`
    })
    class NgTemplateOutletSimpleExample {
      // This field is necessary to expose HelloWorld to the template.
      HelloWorld = HelloWorld;
    }
    
    0 讨论(0)
  • 2021-01-30 17:55

    This you should get what you want:

    @Component({
      selector: 'ul[my-list]',
      template: `
        <ng-content></ng-content>
      `
    })
    export class MyList {
    }
    
    @Component({
      selector: 'li[my-item]',
      template: `
        <ng-content></ng-content>
      `
    })
    export class MyItem {
    ...
    }
    
    <ul my-list>
        <li my-item>One</li my-item>
        <li my-item>Two</li my-item>
    </ul my-list>
    
    0 讨论(0)
  • 2021-01-30 18:00

    There is a hacky workaround solution that may not be supported in older browser versions, but it was working for mine project and I think it is quite easy to integrate without changing or adding a lot of code.

    First you need to change selector of MyItem class/component from element selector

    selector: 'custom-element-name'
    

    to attribute selector

    selector: '[customAttributeName]'
    

    and finally use html slot element to wrap MyItem inside MyList html template

    <slot customAttributeName></slot>
    

    Full code:

    import { Component } from 'angular2/core'
    
    @Component({
      selector: 'my-list',
      template: `
        <ul>
          <slot myItemAsAtribute></slot>
        </ul>
      `
    })
    export class MyList {
    }
    
    
    @Component({
      selector: '[myItemAsAtribute]',
      template: `
          <li *ngFor="let item of items">{{item}}</li>
    
      `
    })
    export class MyItem {
    }
    
    0 讨论(0)
  • 2021-01-30 18:05

    Finally I found solution: injecting ElementRef to MyItem and using its nativeElement.innerHTML:

    MyList:

    import { Component, ContentChildren, QueryList } from 'angular2/core'
    import { MyItem } from './myitem'
    
    @Component({
      selector: 'my-list',
      template: `
        <ul>
          <li *ngFor="#item of items" [innerHTML]="item.innerHTML"></li>
        </ul>
      `
    })
    export class MyList {
      @ContentChildren(MyItem) items: QueryList<MyItem>
    }
    

    MyItem:

    import { Directive, Inject, ElementRef } from 'angular2/core'
    
    @Directive({selector: 'my-item'})
    export class MyItem {
      constructor(@Inject(ElementRef) element: ElementRef) {
        this.innerHTML = element.nativeElement.innerHTML
      }
    }
    

    Working plunk is here

    0 讨论(0)
  • 2021-01-30 18:08

    In the latest angular you can even avoid adding <ng-content></ng-content>

    I've applied is like:

    import {Component} from '@angular/core';
    
    @Component({
        selector: 'div[app-root]',
        templateUrl: 'app.component.html',
        styleUrls: ['app.component.css']
    })
    export class AppComponent {
        title = 'Delegates Presence Reporting';
    }
    

    and the template:

    <div class="centered">
    <h1>{{title}}</h1>
    </div>
    

    index.html

    <body>
    <div app-root></div>
    </body>
    
    0 讨论(0)
提交回复
热议问题