47 votes

Charger dynamiquement un modèle HTML en angular2

J'ai créé un projet en utilisant angular-cli qui contient AppComponent comme suit :

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

Et app.component.html como

<h1>
  Good Morning, {{title}}
</h1>

Donc quand je le construis avec ng build il génère des fichiers comme celui-ci ./dist/main.bundle.js qui contient du code comme suit .

/* 586 */
/***/ function(module, exports) {

module.exports = "<h1>\n  Good Morning, {{title}}\n</h1>\n"

/***/ },
/* 587 */

Cela signifie qu'au moment de la construction, le compilateur/l'éditeur de bundle lit le fichier html et le concatène dans le fichier js généré.

Mais dans mon cas, le html est aussi dynamique et axé sur le contenu du côté serveur. Disons qu'au lieu de html, mon fichier modèle est app.component.jsp et résidant sur un serveur ou un dossier complètement différent.

De plus, ce fichier JSP renvoie parfois <h1>Good Morning, {{title}}</h1> et parfois <h1>Good Afternoon, {{title}}</h1> en fonction de l'heure actuelle du serveur.

Comment réaliser cette fonctionnalité ?

Ce que je comprends, c'est que je dois définir une sorte de fonction de chargement, par exemple : loadDynamicTemplate(template_url)

et j'ai besoin d'utiliser cette fonction de chargement sur la propriété du modèle de décorateur de composant. Dans ce cas, lorsque le fichier main.bundle.JS est généré, il utilise également cette fonction. Ainsi, lors de l'exécution, Angular appellera cette fonction, chargera le HTML par ajax et l'utilisera.

Mise à jour 1

Ici J'ai trouvé quelques différences entre SystemJS et Webpack. J'ai également découvert que nous pouvons charger les fichiers HTML en cours d'exécution si nous utilisons SystemJS. Je pense donc que ce problème peut être résolu avec la configuration de SystemJS. Mais pour cela, un autre problème entre en jeu, bien que je pense que cela pourrait être une question distincte. J'ai donc posté une nouvelle question pour faire le tri. ici .

Si cette question est résolue, j'essaierai probablement avec SystemJS et je posterai la solution ici si elle est utile.

0 votes

Ce n'est pas très courant dans Angular2. Voir stackoverflow.com/questions/34784778/

1 votes

Dans mon cas, tous mes composants auront le même comportement. Et il est vraiment problématique de définir tous mes composants comme dynamiques. Donc, en fait, je suis à la recherche de ce genre de choses. template: "<my-template url='./app.component.html'></my-template>" . Ici my-template pourrait être une directive et il chargera le HTML dynamiquement. En outre, toutes les autres fonctionnalités devraient rester intactes. Il devrait fonctionner de la même manière que templateUrl: './app.component.html'

0 votes

Je comprends que ce n'est pas très courant. En fait, j'ai un système de gestion de contenu côté serveur avec Adobe AEM. Je veux l'utiliser pour sa grande fonctionnalité de création. Angular2 étant un excellent framework, je suis sûr qu'il doit y avoir un moyen de le contourner. (Sans changer tant de code, je veux juste servir les modèles à l'exécution via un appel AJAX uniquement). Merci de m'aider.

38voto

Karbos 538 Points 1917

Vous pourriez utiliser [innerHtml] dans un fichier my-template avec quelque chose comme ceci (je n'ai pas testé) :

@Component({
    selector: 'my-template',
    template: `
<div [innerHtml]="myTemplate">
</div>
`})
export public class MyTemplate {
    private myTemplate: any = "";
    @Input() url: string;
    constructor(http: Http) {
        http.get("/path-to-your-jsp").map((html:any) => this.myTemplate = html);
    }
}

13 votes

Quelque chose comme Good Morning, {{title}} ne sera pas résolu {{title}} de cette façon.

0 votes

Eh bien, le bon Plunker a toujours été là : plnkr.co/edit/uzcYiN Je poste un exemple pour @Partha Sarathi Ghosh

0 votes

Comment forcer la configuration par défaut à servir certains modèles html à partir du dossier du projet ?

18voto

Karbos 538 Points 1917

Pour interpoler un modèle avec des Good Morning, {{title}} vous pouvez utiliser le composant "ng-dynamic" de Suguru Inatomi.

Vous devez d'abord l'installer :

npm install --save ng-dynamic

Puis importez dans votre NgModule :

@NgModule({
  imports: [
    ...
    DynamicComponentModule.forRoot({}),
    ...
  ],
  ...
})
export class AppModule {}    

Enfin, utilisez-le comme ceci :

@Component({
  selector: 'app-root',
  template: '<div *dynamicComponent="template; context: bindings;"></div>'
})
export class AppComponent {
  bindings: any = {title: "Chuck Norris"};
  template: string = `
    <h1>Good Morning, {{title}}</h1>
  `;
  constructor(http: Http) {
    http.get("/path-to-your-jsp").map((html:string) => this.template = html); //<- You may set bindings in request headers...
  }
}

Vous pouvez utiliser des composants dans votre modèle en définissant un SharedModule. J'ai ajouté un bouton personnalisé "my-button" avec succès comme dans l'exemple de la documentation ici : https://github.com/laco0416/ng-dynamic

0 votes

La façon d'écrire le code ici est très complexe si j'ai autant de variables et de méthodes de liaison. J'ai trouvé ici une information supplémentaire sur SystemJs et Webpack. J'ai mis à jour ma question avec les résultats.

0 votes

Pourquoi j'ai une erreur : Can't bind to 'dynamicComponent' since it isn't a known property of 'div' ?

1 votes

L'étoile vous manque peut-être ? *dynamicComponent

3voto

nnoor Points 632

A travaillé avec angular 6

import { Component, Input } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-root',
  template: `
            <div [innerHtml]="myTemplate">
            </div>
          `,
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  private myTemplate: any = '';
  constructor(http: HttpClient) {
    http.get('/service-path', {responseType: 'text'}).subscribe(data => this.myTemplate = data);
  }
}

2voto

nbppp2 Points 100

Il semble que la façon de procéder consiste maintenant à définir le type de réponse (responseType) lorsque vous faites votre demande. HttpClient-Requête de données non-JSON `

@Component({
  selector: 'my-template',
  template: '<div [innerHtml]="myTemplate"></div>'
})
export public class MyTemplate {
  private myTemplate: any = "";
  @Input() url: string;
  constructor(http: Http) {
    http.get("/path-to-your-jsp", { responseType: 'text' })
      .subscribe(
        (data: string) => {
          this.myTemplate = html;
        }
      );
  }
}

`

0voto

Kiran Points 88

Pourquoi ne pas avoir tous les modèles dans un seul fichier et les afficher en fonction de la condition Par exemple, votre ./app.component.html aura l'air de ressembler :

<div *ngIf="isWorld" >
  <h1>  Hello World </h1>
</div>
<div *ngIf="isUniverse" >
  <h1>  Hello Universe </h1>
</div>

Une idée de son effet sur la durée et la taille de la construction ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X