0
votes

* ngSi vous ne masquez pas / n'affiche pas le composant comme prévu

J'appelle ce modal.service.ts à partir d'un composant

    <div class="tooth" >
      <img src="../../assets/tooth-brush.png" alt="tooth-brush" (click)='services()' style='cursor: pointer;'>
      <h5 (click)='services()' style='cursor: pointer;'>Services</h5>
      <app-services *ngIf="serviceText"></app-services>
    </div>

Il est injecté dans options.component.ts ci-dessous ...

import { Component, OnInit, Input } from '@angular/core';
import { ModalService } from '../modal.service';

@Component({
  selector: 'app-options',
  templateUrl: './options.component.html',
  styleUrls: ['./options.component.css'],
  providers: [ModalService]
})
export class OptionsComponent implements OnInit {
  serviceText: boolean = false;
  constructor(private modalService: ModalService) { }

  ngOnInit() {
  }

  services() {
    this.modalService.toggleServices();
  }
}

Le HTML pour le composant d'options est le suivant, et a un écouteur click ...

export class ModalService {
  serviceText: boolean = true;

  toggleServices() {
    this.serviceText = !this.serviceText;
    console.log('test', this.serviceText);
  }
}

Le services () dans les options.component.ts est appelé, qui à son tour appelle le toggleServices () dans le modal .service.ts

La console enregistre "test" et aussi True ou False, qui est le comportement attendu.

MAIS,

Le dans options.component.html ne bascule pas entre l'affichage et le masquage comme je m'y attendais.

Quelqu'un peut-il voir pourquoi cela ne fonctionne pas?

Merci d'avance.


2 commentaires

serviceText est défini à la fois dans le service et dans le composant, choisissez-en un ou renvoyez le composant au service dans le modèle ou créez une propriété.


Rappelez-vous, avoir deux champs nommés serviceText dans deux classes différentes, c'est comme avoir deux gars nommés Steve, un à New York et un à Seattle. Ce n'est pas parce que New York Steve met un quart dans sa poche que Seattle Steve l'a maintenant dans sa poche. En fait, cela signifie le contraire.


3 Réponses :


1
votes

Vous devez initialiser serviceText dans votre composant avec this.modalService.serviceText , ce que vous avez probablement oublié de faire.

De plus, puisqu'il s'agit d'un booléen dans votre service que vous mettez à jour qui est primitif, il serait passé par valeur.

Vous devrez donc réassigner le serviceText dans votre composant avec serviceText dans votre service chaque fois que vous basculez serviceText sur votre service.

Faites cela dans votre composant comme ceci:

import { Component, OnInit, Input } from '@angular/core';
import { ModalService } from '../modal.service';

@Component({
  selector: 'app-options',
  templateUrl: './options.component.html',
  styleUrls: ['./options.component.css'],
  providers: [ModalService]
})
export class OptionsComponent implements OnInit {
  serviceText: boolean = false;
  constructor(private modalService: ModalService) { }

  ngOnInit() {
    this.serviceText = this.modalService.serviceText;
  }

  services() {
    this.modalService.toggleServices();
    this.serviceText = this.modalService.serviceText;
  }
}


8 commentaires

Non, je viens d'utiliser ce code dans mon projet et cela ne fonctionne pas.


@JamesRossCodes Strange. J'ai joint un exemple de démo et je peux le voir fonctionner ici. 🤷🏼‍♂️


Juste pour confirmer - le seul changement que je dois faire est dans les options.component, ts? Ok, vous avez raison, cela montre maintenant le modal. Bonne réponse.


Oui. C'est correct. Tout est là dans le StackBlitz. 😅 Si vous cliquez sur le bouton img , cela changera la visibilité du composant hello .


Je pense que cette approche n'est pas assez bonne pour être acceptée car la méthode toggleServices () à l'intérieur du ModalService peut prendre un certain temps pour effectuer un basculement (si elle effectue un appel asynchrone ou attend un certain temps avant de basculer l'état) donc le serviceText à l'intérieur du composant ne pouvait pas refléter l'état réel à l'intérieur du ModalService.


@ Z.Bolbol, On ne devrait rien considérer seul à moins que cela ne soit spécifiquement mentionné dans l'OP. De plus, il existe n façons différentes d'y parvenir en ajoutant de plus en plus de complexité en fonction de n cas d'utilisation différents. Mais je répondrais uniquement à celui qui est spécifiquement mentionné dans la question. De plus, je ne discuterai pas avec vous si vous avez fait ça juste pour vous venger 😅


créer un observable à l'intérieur du service sera une meilleure approche pour tenir le composant informé du dernier état.


Comme je l'ai dit, il existe n différentes façons de procéder. Pour des cas d'utilisation simples comme ceux-ci, Observable est exagéré. C'est une solution simple qui fait le travail. Et j'ai le droit d'exprimer mes pensées. Vous pouvez suggérer le vôtre dans votre réponse. Cela m'amène à me demander pourquoi vous n'avez pas suggéré l'approche que vous suggérez ici, dans votre réponse. 🤔



-2
votes

vous devez utiliser modalService.serviceText au lieu de serviceText car le ModaService ne met à jour que sa variable interne

ts

<app-services *ngIf="modalService.serviceText"></app-services>

html

constructor(public modalService: ModalService) { }


1 commentaires

Les services doivent idéalement rester privés . Reportez-vous à cette réponse de Deborah pour plus d'informations.



1
votes

serviceText est défini à la fois dans le service et dans le composant, choisissez-en un ou renvoyez le composant au service dans le modèle ou créez une propriété. / p>


2 commentaires

Nous devons éviter autant que possible les setters et les getters. J'ai écrit une réponse concernant le même ici qui en indique la raison.


Vous pouvez également consulter ce fil sur Twitter pour des raisons.