web-dev-qa-db-fra.com

Angular2: rendu/rechargement du template d'un composant

Dans l’idéal, j’aurais besoin de recharger/rendre à nouveau le modèle de mon composant, mais s’il existe un meilleur moyen de le faire, je le mettrai volontiers en œuvre.

Comportement désiré:

J'ai donc un composant pour un élément de menu. Quand (dans un autre composant) je clique sur un IBO (une sorte de 'client', par exemple) est cliqué Je dois ajouter (j'utilise *ngIf) une nouvelle option dans le menu qui serait IBO Details et une liste d'enfants.

IBOsNavigationElement composant (composant de menu):

@Component({
    selector: '[ibos-navigation-element]',
    template: `
        <a href="#"><i class="fa fa-lg fa-fw fa-group"></i> <span
                class="menu-item-parent">{{'IBOs' | i18n}}</span>
        </a>
        <ul>
            <li routerLinkActive="active">
                <a routerLink="/ibos/IBOsMain">{{'IBOs Main' | i18n}} {{id}}</a>
            </li>
            <li *ngIf="navigationList?.length > 0">
                <a href="#">{{'IBO Details' | i18n}}</a>
                <ul>
                    <li routerLinkActive="active" *ngFor="let navigatedIBO of navigationList">
                        <a href="#/ibos/IboDetails/{{navigatedIBO['id']}}">{{navigatedIBO['name']}}</a>
                    </li>
                </ul>
            </li>
        </ul>
    `
})
export class IBOsNavigationElement implements OnInit {
    private navigationList = <any>[];


    constructor(private navigationService: NavigationElementsService) {
        this.navigationService.updateIBOsNavigation$.subscribe((navigationData) => {
                this.navigationList.Push(navigationData);
                log.d('I received this Navigation Data:', JSON.stringify(this.navigationList));
            }
        );
    }

    ngOnInit() {
    }
}

Initialement, navigationList sera vide [], car l'utilisateur n'a pas cliqué sur un IBO (client), mais dès qu'un IBO est cliqué, la liste sera remplie et, par conséquent, la nouvelle option doit apparaître dans le menu.

Avec ce code, lorsque je clique sur un PCI, l'élément <li> et ses enfants sont créés, mais: je ne vois que l'élément <li>.

Problème:

L'option de menu est générée mais non traitée par les styles de mise en page. Il doit être initialisé avec tous les éléments pour savoir comment afficher les options du menu.

Je dois recharger le modèle de ce composant afin d'afficher correctement le menu.

REMARQUE:

Si j'utilise le modèle sans le *ngIf, cela fonctionne bien, mais j'aurais dès le premier instant une option IBO Details qui n'a aucun sens, car aucun IBO n'a été cliqué lors de l'initialisation.

template: `
        <a href="#"><i class="fa fa-lg fa-fw fa-group"></i> <span
                class="menu-item-parent">{{'IBOs' | i18n}}</span>
        </a>
        <ul>
            <li routerLinkActive="active">
                <a routerLink="/ibos/IBOsMain">{{'IBOs Main' | i18n}} {{id}}</a>
            </li>
            <li>
                <a href="#">{{'IBO Details' | i18n}}</a>
                <ul>
                    <li routerLinkActive="active" *ngFor="let navigatedIBO of navigationList">
                        <a href="#/ibos/IboDetails/{{navigatedIBO['id']}}">{{navigatedIBO['name']}}</a>
                    </li>
                </ul>
            </li>
        </ul>
    `

Sortie désirée:

Avant de cliquer sur quelque chose (sur init):

 enter image description here

Après avoir cliqué sur un IBO (client):

 enter image description here

Mise à jour 1:

Pour clarifier ce que je voulais dire par: 

L'option de menu est générée mais non traitée par les styles de mise en page

Si mon composant de menu est initialisé sans le *ngIf:

<li>
    <a href="#">{{'IBO Details' | i18n}}</a>
        <ul>
            <li routerLinkActive="active" *ngFor="let navigatedIBO of navigationList">
                <a href="#/ibos/IboDetails/{{navigatedIBO['id']}}">{{navigatedIBO['name']}}</a>
            </li>
        </ul>
</li>

Ensuite, les styles de mise en page peuvent générer la sortie du menu (voir images) en fonction de cette structure:

<li>
   <a>
   <ul>
      <li *ngFor>
         <a>
      </li>
   </ul>
</li>

Et donc ajoutez le symbole + et le comportement du sous-menu, etc.

Mais s'il est initialisé sans tous les éléments (lorsque *ngIf est false le <li> et que ses enfants ne sont pas restitués, la mise en page ne les prend pas en compte pour dessiner/créer le menu) et ces éléments sont ajoutés après le rendu. , alors ils existeront dans le code source, mais nous ne pourrons pas les voir dans le menu car:

  • Pas de + créé
  • Pas de comportement de sous-menu
5
SrAxi

Angular a deux stratégies de détection de changement:

La stratégie OnPush peut améliorer les performances lorsque vous avez plusieurs éléments sur une page ou lorsque vous souhaitez davantage de contrôle sur le processus de rendu.

Pour utiliser cette stratégie, vous devez la déclarer dans votre composant:

@Component({
    selector: '[ibos-navigation-element]',
    template: `...`,
    changeDetection: ChangeDetectionStrategy.OnPush
})

Et injectez dans votre constructeur:

constructor(
    private changeDetector: ChangeDetectorRef,
) {}

Lorsque vous souhaitez déclencher la détection des modifications afin que le composant puisse être restitué (Dans votre cas, juste après l'ajout d'un nouveau client/opérateur indépendant au modèle), appelez:

this.changeDetector.markForCheck();

Consultez la démonstration en direct à partir du didacticiel officiel: http://plnkr.co/edit/GC512b?p=preview

Si le problème ne concerne pas la détection des modifications, mais plutôt le style CSS/SCSS, Tient compte du fait que dans Angular 2, chaque composant possède son propre ensemble de classes CSS et que Ne sont pas "hérités "par les éléments" enfants ". Ils sont complètement isolés les uns des autres. Une solution pourrait être la création de styles globaux CSS/SCSS.

4
Pedro Penna

Essayez d'utiliser ChangeDetectorRef.detectChanges () - cela fonctionne beaucoup comme $ scope. $ Digest () from Angular.

Remarque: ChangeDetectorRef doit être injecté dans le composant.

0
n0k