Search code examples
angularangular2-templateangular2-directives

Use content of component template in angular 2


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>.


Solution

  • 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