3
votes

angulaire: utiliser le même deux fois dans un composant

Clause de non-responsabilité: Ceci est une copie de Changer de routeur-sortie avec * ngIf dans app.component.html dans angular2 qui a une réponse acceptée qui ne résout pas ma situation cependant.

Voici donc mon problème: j'aimerais avoir le même "routeur -outlet "deux fois dans mon composant principal. Comme il semble, seul le deuxième "routeur-sortie" l'emporte et affiche correctement le contenu. La solution proposée pour envelopper la sortie du routeur dans un ng-template ne fonctionne pas pour moi.

Voici ma situation dans le code:

<div class="mobile-only">
  <div>some special content for mobile version</div>
  <router-outlet></router-outlet>
</div>

<div class="desktop-only">
  <div>some special content for desktop version</div>
  <router-outlet></router-outlet>
</div>

Seulement la deuxième sortie de routeur est mise à jour lorsque l'utilisateur navigue sur la page. Le premier routeur-sortie est abandonné par angulaire.

Question: Comment puis-je réutiliser le routeur-sortie?

Edit: j'ai essayé d'envelopper le router-outlet dans un ng-template, cela n'a pas fonctionné cependant: https://stackblitz.com/edit/router-outlet-in-template-not-working-example-cpyjbq

Et voici une version de travail: https://stackblitz.com/edit/router-outlet-in-template-working- exemple

Je peux en fait réutiliser la sortie du routeur --- mais seulement au prix de réaffecter la variable-modèle dans un setTimeout. En tant qu'effet secondaire désagréable, les composants sont rétablis.


0 commentaires

4 Réponses :


2
votes

Si vous souhaitez utiliser plusieurs prises dans le même modèle de composant, vous devez utiliser points de vente nommés . Mais ils sont destinés à fonctionner avec des routes secondaires et non avec des routes principales ... Je ne sais pas quel est votre cas d'utilisation pour avoir deux points de vente, mais si vous allez afficher un contenu différent à partir du mobile et du bureau, vous devriez plutôt envisager de créez deux applications différentes, mais ce n'est qu'une recommandation!

Donc, si vous souhaitez utiliser des points de vente nommés, vous devez donner à chaque point de vente un nom, comme ceci:

<a [routerLink]="[{ outlets: { mobile-content: ['mobile'] } }]">Mobile Content</a>
<a [routerLink]="[{ outlets: { desktop-content: ['desktop'] } }]">Desktop Content</a>

Ensuite, vous pouvez rediriger vos itinéraires vers une prise spécifique sur votre fichier de routage comme ceci:

{
  path: 'mobile',
  component: MobileContentComponent,
  outlet: 'mobile-content'
},
{
  path: 'desktop',
  component: DesktopContentComponent,
  outlet: 'desktop-content'
}

Si vous redirigez vers ces itinéraires via un routerLink code>, alors vous pouvez rediriger à partir du modèle comme ceci:

<div class="mobile-only">
  <div>some special content for mobile version</div>
  <router-outlet name="mobile-content"></router-outlet>
</div>

<div class="desktop-only">
  <div>some special content for desktop version</div>
  <router-outlet name="desktop-content"></router-outlet>
</div>

EDIT

Je viens de voir votre code sur StackBlitz et le problème est que vous affichez le modèle de sortie du routeur deux fois dans le modèle. Vous devez afficher l'un ou l'autre en fonction d'une condition. J'ai modifié votre StackBlitz ici a > avec une variable qui afficherait une ou une autre prise de routeur en fonction d'une condition (vous pouvez vérifier la taille de l'écran ou ce que vous voulez).

Mais en examinant votre code, je ne comprends pas pourquoi vous en avez besoin de deux sorties du routeur ... Si vous souhaitez uniquement déclencher une classe sur la div parent de la sortie du routeur, vous pouvez simplement utiliser ngClass pour utiliser une classe ou une autre en fonction de la taille de l'écran.


6 commentaires

Merci pour votre réponse! Malheureusement, je ne peux pas utiliser des itinéraires différents pour différentes tailles d'écran ...


Existe-t-il un moyen de simplement répéter le même contenu de la sortie du routeur? J'ai essayé de le mettre dans un ng-template, mais cela n'a pas fonctionné non plus ...


Pourquoi pas? Si vous déclenchez la redirection d'itinéraire à partir des fichiers .ts, vous pouvez vérifier la taille de l'écran et charger une route ou une autre en fonction de la taille de l'écran. Quoi qu'il en soit, l'approche recommandée serait d'avoir deux applications différentes ...


Aussi oui, j'ai essayé l'astuce ng-template dans un projet plus ancien et cela fonctionnait bien ... Pouvez-vous partager du code de ce que vous avez essayé dans un Stackblitz pour vous aider?


(J'avais besoin du routeur-sortie deux fois car le modèle html est assez complexe et plus complexe que dans mon exemple sur stackblitz) Merci encore! :-)


J'ai le même problème et utiliser des itinéraires différents n'est pas une possibilité. J'ai essayé d'utiliser un package npm qui me permettait de détecter les tailles d'écran, mais seule la deuxième sortie fonctionne correctement même si dans le html résultant, il n'y a qu'une seule sortie.



0
votes

Je pense avoir trouvé une autre solution en écoutant Router-Events:

https://stackblitz.com/edit/router-outlet-twice -avec-événements

Dans ce stackblitz, j'ai en fait deux modèles utilisant simultanément la sortie du routeur. Est-ce une solution de contournement valide?


0 commentaires

0
votes

En essayant de trouver une solution à ce problème, je me suis retrouvé avec:

HTML

export class ExampleComponent implements AfterViewInit {

  private initied: boolean
  constructor (
    private cdref: ChangeDetectorRef
  ) { }

  ngAfterViewInit (): void {
    this.initied = true
    this.cdref.detectChanges()
  }

  get isDesktop (): boolean {
    if (!this.initied) { return false }
    return this.checkHidden('router-mobile')
  }

  get isMobile (): boolean {
    if (!this.initied) { return false }
    return this.checkHidden('router-desktop')
  }

  private checkHidden (id: string): boolean {
    return (document.getElementById(id).getAttribute('style') as string).includes('display: none')
  }
}

TS

<div id="mobile">
 <router-outlet *ngIf="isMobile"></router-outlet>
</div>
<div id="desktop">
 <router-outlet *ngIf="isDesktop"></router-outlet>
</div>


0 commentaires

0
votes

J'ai essayé quelque chose comme suit et m'aide à afficher

HTML

get getIfMobile() {
    return window.innerWidth < 720;
}

Component.ts

<div id="mobile">
 <router-outlet *ngIf="!getIfMobile"></router-outlet>
</div>
<div id="desktop">
 <router-outlet *ngIf="getIfMobile"></router-outlet>
</div>


1 commentaires

Bien que ce code puisse répondre à la question, fournir un contexte supplémentaire sur la manière et / ou la raison pour laquelle il résout le problème améliorerait la valeur à long terme de la réponse.