2017-09-15 8 views
1

J'ai différents onglets qui montrent des rubans avec des composants. Ce que je dois faire est de cacher ces composants quand le projet n'est pas chargé (indéfini), et montrer quand un projet quelconque de la liste déroulante est chargé. Pour cela, j'ai besoin de récupérer la valeur de l'identifiant ou du nom du projet, et ensuite, le reste des composants du ruban peut être affiché.Afficher le composant en fonction de la valeur - Angulaire 2

Comme vous pouvez le voir, c'est l'un des onglets avec des composants:

<div class="tab tab-style"> 

<ribbon-item style="width:10%;" [title]="'Load/Save Project'"> 
    <project></project> 
</ribbon-item> 
<div class="ribbon-divider"></div> 

<ribbon-item style="width:12%;" [title]="'Project settings'"> 
    <project-settings></project-settings> 
</ribbon-item> 
<div class="ribbon-divider"></div> 

<ribbon-item style="width:23%;" [title]="'Environment'"> 
    <environment></environment> 
</ribbon-item> 
<div class="ribbon-divider"></div> 

<ribbon-item class="pd-width" [title]="'Project dates'"> 
    <project-dates></project-dates> 
</ribbon-item> 
<div class="ribbon-divider"></div> 

Et c'est un composant de projet de cet onglet qui ont project.id:

<div class="button-wrapper"> 
<select #projectSelect class="custom-select custom-select-project" (change)="loadProject(projectSelect.value)"> 
    <option selected disabled>Open projects</option> 
    <option *ngFor="let project of projects" [value]=project.id>{{project.name}}</option> 
</select> 

<button class="btn-main" (click)="createNewProject()">New project</button> 
<button class="btn-main">Save project</button> 
<button class="btn-main">Save as</button> 

question de base est, comment puis-je mettre mes autres composants (sauf project.component) t o show, basé sur la valeur d'identifiant ou la forme de données de ce composant? Puis-je utiliser ngIf ou quelque chose comme ça? Merci pour l'aide

Répondre

1

Passé un certain temps à assembler une base très simple pour l'idée d'entrées et de sorties (la liaison de données bidirectionnelle utilisée par Angular), avec des composants imbriqués, ainsi que la "transclusion" (où vous incluez un composant dans la zone de contenu d'un autre composant).

Ce Plunk est here.

Les faits saillants sont exactement comme pezetter décrits: dans le composant de l'enfant qui est émission d'une valeur, vous aurez envie d'utiliser EventEmitter et Output:

// SelectorComponent 
@Output() valueSelected: EventEmitter<number> = new EventEmitter(); 
selectValue(val: number) { 
    this.valueSelected.emit(val); 
} 

qui sera appelé sur l'événement (change) de votre <select> composant .

// SelectorComponent  
<select #selectorElem (change)="selectValue(selectorElem.value)"> 

Le parent veille alors pour cet événement émis

// ParentComponent (template) 
<selector design="purple" (valueSelected)="valueChanges($event)"></selector> 

// ParentComponent 
selectedVal: string;  
valueChanges(val: number) { 
    this.selectedVal = val; 
} 

Enfin, vous avez juste besoin de vos composants qui seront cachés ou montrant de le faire en fonction de la valeur qui a été délivrée (passé jusqu'à le parent). Dans le Plunk, il y a 2 façons différentes cela est fait: un * ngIf sur le composant lui-même (alt-child):

// ParentComponent  
<alt-child design="gray" *ngIf="selectedVal"> 

ou un * ngIf dans le composant (child)

// ParentComponent 
<child design="red" [value]="selectedVal" [position]="2"> 

// ChildComponent 
<div [ngClass]="design" *ngIf="value >= position"> 

C'est tous certainement plus en profondeur que nécessaire pour comprendre, mais j'espère que certains trouveront utile de jouer avec cette technique utile.

+0

Merci, juste ce que je cherchais :) Cela va résoudre mon problème à coup sûr –

+0

Content de vous aider :) –

+0

Cela ne vous dérangerait pas de m'aider avec ce chat privé? J'ai un code spécifique que j'ai besoin de mettre en œuvre, mais je n'arrive pas à le faire fonctionner. Je pourrais vous envoyer des fichiers et expliquer. Je crois que ce sera simple pour vous: D –

1

Ajouter un @output à la composante du projet. Ensuite, émettez un événement qui contient la valeur de votre projet qui activera les autres composants avec un ngIf ou quelque chose de similaire.

Dans votre project.component.ts:

@Output() setProjectValue = new EventEmitter(); 

loadProject(val){ 
    let foundProject; 
    //Load project logic here... 
    foundProject == ...; // once its done: 
    this.setProjectValue.emit(foundProject); //This will output to your parent component. 
} 

Dans votre app.component.html (ou quel que soit le parent est de composante du projet):

<project (setProjectValue)="project = $event;"></project> //I think you're allowed to bind like this. 

Cependant, je recommande simplement utiliser un service/fournisseur pour stocker un projet chargé. Définissez cette valeur chaque fois qu'un projet est chargé et utilisez une condition dans ce composant parent qui vérifie si le service a une valeur de projet chargée.

0

Vous pouvez envisager d'utiliser le routage au lieu de composants imbriqués pour votre interface utilisateur à onglets.

Le code HTML serait alors ressembler à quelque chose comme ceci:

<div class="panel-body"> 
    <div class="wizard"> 
     <a [routerLink]="['info']" routerLinkActive="active"> 
      Basic Information <span [ngClass]="{'glyphicon glyphicon-exclamation-sign': 
                !isValid('info')}"></span> 
     </a> 
     <a [routerLink]="['tags']" routerLinkActive="active"> 
      Search Tags <span [ngClass]="{'glyphicon glyphicon-exclamation-sign': 
                !isValid('tags')}"></span> 
     </a> 
    </div> 

    <router-outlet></router-outlet> 
</div> 

Il y a essentiellement les onglets et une prise de routeur.

Ensuite, vous pouvez facilement transmettre des données aux différents itinéraires à l'aide des paramètres d'itinéraire.

J'ai un exemple complet de ce ici: https://github.com/DeborahK/Angular-Routing dans le dossier APM-finale.