Use content of component template in angular 2 [duplicate]

梦想与她 提交于 2019-12-11 11:49:59

问题


RE DUPLICATE: "This question has been asked before and already has an answer. "

So this question was asked 10 days after I asked it? Somebody doesn't know how to read time stamps.


I'm struggling with Angular 2 making it hard or perhaps impossible to do things that were trivial in Angular 1, especially without tons of superfluous code and/or DOM nodes. :(

In Angular 1 I had a query control that did sophisticated handling of keystrokes in an input box and dynamically displayed results in a dropdown list. The items being searched could be of any type, and the dropdown list items could be simple strings or complex inline templates.

For example, I might use it query a list of User objects and display them using a default template (e.g. toString):

  <search-box [query-provider]='userFinder'> </search-box>

Somewhere else I have a similar search, but I want the resulting list to contain a richer view of each user, so I provide a template inline, as a child of the search-box:

  <search-box [query-provider]='userFinder'>
       <!-- this is used as a template for each result item in the
            dropdown list, with `result` bound to the result item. -->
       <div>
            <span class='userName'>result.name</span>
            <span class='userAge'>result.age</span>
            <address [model]='result.address'><address>
       </div>
  </search-box>

My implementation of search-box needs to determine if there is any child content to use as a template and use it in the correct location in the search-box template.

@Component({
    select: 'search-box',
    template: `
        <div somestuff here>
            <input morestuff here>
            <ul this is where my dropdown items will go>
                <li *ng-for="#item of model.listItems"
                    TEMPLATE FOR ITEMS SHOULD GO HERE
                </li>
            </ul>
        </div>`
    ...

With Angular 1 I could easily transclude a child template to that location and bind it to the appropriate scope, or I could dynamically compiled a template. I can't get this to work in Angular 2 at all.

If I use <ng-content> there, it only appears in the first <li>.


回答1:


You can do this easily with ngForTemplate, here is my detailed answer for a similar question Custom template(transclusion without ng-content) for list component in Angular2

https://stackoverflow.com/a/36535521/306753




回答2:


In Angular2 there are

  • DynamicComponentLoader (Plunker example)

See also Angular 2 dynamic tabs with user-click chosen components

which can be used like:

  constructor(private dcl: DynamicComponentLoader, private injector: Injector, private ref:ElementRef) {}

  ngAfterViewInit() {
    this.dcl.loadIntoLocation(ChildComponent, this.ref, 'child').then((cmp) => {
      cmp.instance.someProperty = 'xxx';
    });
  }
  • TemplateRef and ViewContainerRef (Plunker example not created by me, I hope the creator doesn't mind)



回答3:


I made some tests and this doesn't seem to be supported. The following doesn't work:

@Component({
  selector: 'sub',
  template: `
    Sub component : 

    <h3>#1</h3>

    <template ngFor #elt [ngForOf]="list">
      <div>{{elt}}</div>
      <ng-content></ng-content>
    </template>

    <h3>#2</h3>

    <ng-content ngFor #elt [ngForOf]="list"></ng-content>
  `
})

Even with the template syntax for loops.

This works however when providing the content. This could perhaps be a workaround for you.

@Component({
  selector: 'my-app',
  template: `
    <sub>
      <div>from parent</div>
      <template ngFor #elt [ngForOf]="list">
        <div>{{elt}} - parent</div>
      </template>
    </sub>
  `,
  directives: [ SubComponent ]
})

See the plunkr I used for my tests: https://plnkr.co/edit/a06vVP?p=preview.

I also saw an issue regarding this (and slot):

  • https://github.com/angular/angular/issues/3397


来源:https://stackoverflow.com/questions/36353103/use-content-of-component-template-in-angular-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!