2016-02-17 2 views
10

У меня есть json-массив, который может содержать либо компонент, либо селектор html для компонента, который я хочу загрузить. Я пытаюсь загрузить эти данные в цикл for. Когда я пытаюсь интерполировать значение {{d.html}}, он отображается как текст плана. Когда я использую метод innerHTML ниже и проверяю dom, я вижу html там, но он не ведет себя как пользовательский компонент (dom будет просто содержать вместо инициализации и заменять его шаблоном компонентов.Angular2 loading dynamic content/html in for loop

У меня есть внешний вид в динамическом загрузчике контента, но это не похоже на соответствие. Это находится в цикле for и поэтому не может использовать синтаксис шаблона, поэтому loadIntoLocation не будет работать для меня. Также не уверен, как он будет работать, если компонент имеет какие-либо данные.

<div *ngFor="#d of dtabs" class="tab-pane" id="tab-{{d.component}}"> 
    <div [innerHTML]="d.html"></div> 
</div> 

ответ

9

Я также искал способ сделать это. Я увидел ответ @guyoung и построил что-то на этом основании. Но потом я понял, что DynamicComponentLoader.loadIntoLocation() больше не существует в последней версии, а DynamicComponentLoader уже устарел.

Я прочитал некоторые документы и сообщения и создал новую Директиву, которая отлично работала. Проверьте:

import { 
 
    Component, 
 
    ComponentResolver, 
 
    Directive, 
 
    ViewContainerRef, 
 
    Input, 
 
    Injector, 
 
    ApplicationRef 
 
} from "@angular/core"; 
 

 
/** 
 

 
    This component render an HTML code with inner directives on it. 
 
    The @Input innerContent receives an array argument, the first array element 
 
    is the code to be parsed. The second index is an array of Components that 
 
    contains the directives present in the code. 
 

 
    Example: 
 

 
    <div [innerContent]="[ 
 
    'Go to <a [routerLink]="[Home]">Home page</a>', 
 
    [RouterLink] 
 
    ]"> 
 

 
**/ 
 
@Directive({ 
 
    selector: '[innerContent]' 
 
}) 
 
export class InnerContent { 
 

 
    @Input() 
 
    set innerContent(content){ 
 
    this.renderTemplate(
 
     content[0], 
 
     content[1] 
 
    ) 
 
    } 
 

 
    constructor(
 
    private elementRef: ViewContainerRef, 
 
    private injector: Injector, 
 
    private app: ApplicationRef, 
 
    private resolver:ComponentResolver){ 
 
    } 
 

 
    public renderTemplate(template, directives) { 
 
    let dynComponent = this.toComponent(template, directives) 
 
    this.resolver.resolveComponent(
 
     dynComponent 
 
    ).then(factory => { 
 
     let component = factory.create(
 
     this.injector, null, this.elementRef._element.nativeElement 
 
    ); 
 

 
     (<any>this.app)._loadComponent(component); 
 
     component.onDestroy(() => { 
 
     (<any>this.app)._unloadComponent(component); 
 
     }); 
 
     return component; 
 
    }); 
 
    } 
 

 
private toComponent(template, directives = []) { 
 
    @Component({ 
 
    selector: 'gen-node', 
 
    template: template, 
 
    directives: directives 
 
    }) 
 
    class DynComponent {} 
 
    return DynComponent; 
 
    } 
 
}

+0

Я думаю, что этот фрагмент потребности идти в угловых документы. Я использовал визуализацию встроенного компонента в шаблоне, полученном на сервере, и он отлично работал. Большое спасибо. –

+0

Это должно быть официальным ответом – dopatraman

+7

ComponentResolver был обесценен. Не могли бы вы обновить? Спасибо – x0a

3

Angular2 Динамически Рендер шаблона

import { Component, View, DynamicComponentLoader, ElementRef} from 'angular2/core'; 
import {bootstrap} from 'angular2/platform/browser' 
@Component({ 
    selector: 'some-component', 
    properties: ['greeting'], 
    template: ` 
    <b>{{ greeting }}</b> 
    ` 
}) 
class SomeComponent { } 
@Component({ 
    selector: 'app' 
}) 
@View({ 
    template: ` 
    <h1>Before container</h1> 
    <div #container></div> 
    <h2>After container</h2> 
    ` 
}) 
class App { 
    loader: DynamicComponentLoader; 
    elementRef: ElementRef; 

    constructor(loader: DynamicComponentLoader, elementRef: ElementRef) { 
     this.laoder = loader; 
     this.elementRef = elementRef; 

     // Some async action (maybe ajax response with html in it) 
     setTimeout(() => this.renderTemplate(` 
     <div> 
    <h2>Hello</h2> 
    <some-component greeting="Oh, hey"></some-component> 
     </div> 
    `, [SomeComponent]), 1000); 
    } 

    renderTemplate(template, directives) { 
     this.laoder.loadIntoLocation(
      toComponent(template, directives), 
      this.elementRef, 
      'container' 
     ) 
    } 
} 
function toComponent(template, directives = []) { 
    @Component({ selector: 'fake-component' }) 
    @View({ template, directives }) 
    class FakeComponent { } 

    return FakeComponent; 
} 


bootstrap(App); 

полный код: https://github.com/guyoung/GyPractice-Angular2Advanced/tree/master/apps/dynamically_render_template