J'essaie de trouver la solution de ce problème depuis deux jours. Malheureusement, je ne peux pas obtenir ce que je veux. J'utilise Angular5.
<div class="form-group col-md-12" [innerHTML]="GetItemsOfHolder(item.children[1],1,
'UserConfigGroupsLabelHolder') | keepHtml"></div>
Voici à quoi ressemble ma fonction:
GetItemsOfHolder(item: any,divName:string, recursive: boolean = false,typeName:string="")
{
return html;
}
Tout fonctionne bien, sauf si le html que je retourne contient un paquet nommé Select2 Voici ce que j'utilise pour ajouter le html dans ce div, cela fonctionne très bien. Jusqu'à ce que je veuille ajouter le package dynamique.
Ce que je veux dire, c'est que html de retour contient le composant du package comme ceci:
itemhtml +="<select2 data-type='"+holderItem.itemType+"'
[data]='this.dropdownData."+holderItem.name+"'></select2>"
Cela renvoie simplement le texte brut au navigateur et ne fonctionne pas comme prévu.
Ce que je veux, c'est que la chaîne soit transformée en composant ou de toute autre manière qui fonctionne et génère la liste déroulante select2.
J'ai essayé de chercher tellement de choses, mais cela ne fonctionne pas C'est bien mais je ne peux pas comprendre cela Et le chargement dynamique des composants est déconseillé.
Quelqu'un peut-il me donner une idée Comment puis-je résoudre ce problème? Tout exemple serait formidable.
Comme l'a commenté @Devcon
Angular désinfectera à peu près tout, c'est pourquoi vous obtenez du texte brut. Ce que vous voulez examiner est ReflectiveInjector et principalement ComponentFactoryResolver. L'idée principale est que les composants ont besoin d'autres informations (services, autres composants, etc.) pour être rendus, vous utilisez donc l'injecteur pour obtenir les références d'injection de dépendance, puis la fabrique de composants construit votre composant. Vous l'insérez ensuite dans une référence ViewChild. Il existe un moyen plus compliqué de créer dynamiquement des composants qui utilisent le compilateur et nécessitent un ModuleWithComponentFactories, c'est ce que angular utilise réellement).
Et en cherchant sur l'angulaire, j'accepte que angular ne doit pas être fait de cette façon.
Comme je dois créer la page entièrement dynamique qui doit être rendue en html. J'ai changé mon json un peu et en utilisant le ng-container et ng-template et en utilisant ngswitch J'ai fait un appel récursif dans le modèle lui-même et trouvé son fonctionnement très bien.
J'obtiens de nombreux avantages en utilisant ceci: le HTML (je rends dynamiquement) lui-même est en HTML, le code est propre et lisible, facilement maitainable.
L'exemple donné ici est à peu près le même que j'ai fait. https://stackoverflow.com/a/40530244/2630817
Un petit exemple est ici:
<ng-template #itemsList let-itemsList>
<div *ngFor="let item of itemsList;let i = index">
<div [ngSwitch]="item.itemType">
<div class="form-group" *ngSwitchCase="'TEXT'">
<label>
{{item.label}}
</label>
<input id="{{item.name}}" value="{{item.value}}" type='text' class='form-control txtbox ui-autocomplete-input'/>
</div>
<div class="form-group" *ngSwitchCase="'PASSWORD'">
<label>
{{item.label}}
</label>
<input id="{{item.name}}" value="{{item.value}}" type='password' class='form-control txtbox ui-autocomplete-input'/>
</div>
<div class="form-group" *ngSwitchCase="'BOOLEAN'">
<label style='width:40%'>{{item.label}}</label>
<div class="form-group"><input id="{{item.name}}" type='checkbox' /></div>
</div>
<div class="form-group" *ngSwitchCase="'LABEL'">
<label class="form-control">{{item.label}}</label>
</div>
<div class="form-group" *ngSwitchDefault>
<label>
{{item.label}}
</label>
<select2 class="form-control" [data]="GetDropDowndata(item.holderId)" [cssImport]="false" [width]="300" [options]="GetOptions(item.type)"></select2>
</div>
</div>
</div>
Vous pouvez charger tout ce que vous voulez dans une seule div, vous devez jouer avec ng-template et ng-content.
Vous devez d'abord créer une directive:
import {Directive, ViewContainerRef} from '@angular/core';
@Directive({
selector: '[dynamic]',
exportAs: 'dynamicdirective'
})
export class DynamicDirective {
constructor(public viewContainerRef: ViewContainerRef) { }
}
Après vous devez le mettre dans un modèle ng comme:
<p>
page works!
</p>
<ng-template #sider=dynamicdirective dynamic></ng-template>
et l'utiliser comme
import {Component, ComponentFactoryResolver, OnInit, ViewChild} from '@angular/core';
@Component({
selector: 'app-page',
templateUrl: './page.component.html',
styleUrls: ['./page.component.css']
})
export class PageComponent implements OnInit {
@ViewChild('sider')
sider;
constructor(private componentFactoryResolver: ComponentFactoryResolver) {
}
ngOnInit() {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(SomeComponent);
this.sider.viewContainerRef.createComponent(componentFactory);
});
}
}
et normalement vous verrez le composant chargé à l'endroit de votre ng-template (vous pouvez appeler https://angular.io/api/core/ViewContainerRef#clear si vous voulez réinitialiser votre vue)
Je joue déjà avec ça, vous pouvez trouver du code ici https://github.com/nicearma/dynamic