2017-12-29 32 views
1

Ich wollte eine HTML-Daten über Service-Aufruf an den Server (das ist sicher. Ich kann nicht Vorlagen in lokalen halten) und manipulieren sie intern auf wie man es zeigt (entweder als modale oder ganze Seite). Dieser HTML-Code mit Angular-Tags sollte zu einer Komponente geloopt werden und zusammen funktionieren. Höchstens Art von $ kompilieren in Angular JS.

Ich entwickle die Lösung in Angular 5 und sollte mit AOT-Compiler kompatibel sein. Ich hatte mehrere Lösungen genannt und war bei den veralteten und aktualisierten Lösungen verwirrt. Bitte hilf mir. Ich glaube, Ihre aktualisierte Antwort würde auch vielen anderen Menschen helfen. Vielen Dank im Voraus!

Antwort

1

Um HTML im laufenden Betrieb zu rendern, benötigen Sie DomSanitizer. Z.B. so etwas wie diese:

<!-- template --> 
<div [innerHTML]="htmlData"></div> 

// component 
import { Component } from '@angular/core'; 
import { DomSanitizer } from '@angular/platform-browser'; 

@Component({ 
    selector: 'my-app', 
    templateUrl: './app.component.html', 
    styleUrls: [ './app.component.css' ] 
}) 
export class AppComponent { 
    htmlData: any; 
    constructor(private sanitizer: DomSanitizer) {} 

    ngOnInit() { 
    this.htmlData= this.sanitizer.bypassSecurityTrustHtml('<div style="border: 1px solid red;"><h2>Safe Html</h2><span class="user-content">Server prepared this html block.</span></div>'); 
    } 
} 

Nun, das ist der Kern von ihm. Sie brauchen natürlich auch eine Lademechanik. Sie könnten auch einige Daten in diesem Block enthalten sein sollen - wenn es einfach Daten ist, kann es im laufenden Betrieb sein:

this.htmlData= this.sanitizer.bypassSecurityTrustHtml(`<div>${this.someValue}</div>`); 

Für komplexere Szenarien, die Sie benötigen eine dynamische Komponente zu erstellen.

Bearbeiten: ein Beispiel für eine Komponente dynamisch aufgelöst. Mit diesem erstellen Sie eine Komponente on-the-fly von Server-sended HTML.

@Component({ 
    selector: 'my-component', 
    template: `<h2>Stuff bellow will get dynamically created and injected<h2> 
      <div #vc></div>` 
}) 
export class TaggedDescComponent { 
    @ViewChild('vc', {read: ViewContainerRef}) vc: ViewContainerRef; 

    private cmpRef: ComponentRef<any>; 

    constructor(private compiler: Compiler, 
       private injector: Injector, 
       private moduleRef: NgModuleRef<any>, 
       private backendService: backendService, 
      ) {} 

    ngAfterViewInit() { 
    // Here, get your HTML from backend. 
    this.backendService.getHTMLFromServer() 
     .subscribe(rawHTML => this.createComponentFromRaw(rawHTML)); 
    } 

    // Here we create the component. 
    private createComponentFromRaw(template: string) { 
    // Let's say your template looks like `<h2><some-component [data]="data"></some-component>` 
    // As you see, it has an (existing) angular component `some-component` and it injects it [data] 

    // Now we create a new component. It has that template, and we can even give it data. 
    const tmpCmp = Component({ template, styles })(class { 
     // the class is anonymous. But it's a quite regular angular class. You could add @Inputs, 
     // @Outputs, inject stuff etc. 
     data: { some: 'data'}; 
     ngOnInit() { /* do stuff here in the dynamic component */} 
    }); 

    // Now, also create a dynamic module. 
    const tmpModule = NgModule({ 
     imports: [RouterModule], 
     declarations: [tmpCmp], 
     // providers: [] - e.g. if your dynamic component needs any service, provide it here. 
    })(class {}); 

    // Now compile this module and component, and inject it into that #vc in your current component template. 
    this.compiler.compileModuleAndAllComponentsAsync(tmpModule) 
     .then((factories) => { 
     const f = factories.componentFactories[0]; 
     this.cmpRef = f.create(this.injector, [], null, this.moduleRef); 
     this.cmpRef.instance.name = 'my-dynamic-component'; 
     this.vc.insert(this.cmpRef.hostView); 
     }); 
    } 

    // Cleanup properly. You can add more cleanup-related stuff here. 
    ngOnDestroy() { 
    if(this.cmpRef) { 
     this.cmpRef.destroy(); 
    } 
    } 
} 
+0

Vielen Dank für Ihre Antwort. Ich habe diese Methode versucht, die nur HTML-Ansicht gerendert hat. Ich möchte, dass Angular-Tags in der Vorlage funktionieren. – Srini

+0

Damit die Tags auch funktionieren, können Sie eine Komponente im laufenden Betrieb starten. – Zlatko

+0

@Srini überprüfen Sie die bearbeitete Antwort. – Zlatko

Verwandte Themen