53 votes

NgrxStore et Angular - Utilisez le pipe async massivement ou abonnez-vous une seule fois dans le constructeur

Je commence à regarder ngrx Magasin et je vois la commodité d'utiliser l'angle async pipe. En même temps, je ne suis pas sûr de savoir si l'aide de l'angle async pipe massivement est un bon choix.

Je fais un exemple simple. Supposons que, dans le même modèle j'ai besoin de montrer les différents attributs d'un objet (par exemple, une Personne) qui est extrait à partir de la Boutique.

Un morceau de code de modèle pourrait être

<div>{{(person$ | async).name}}</div>
<div>{{(person$ | async).address}}</div>
<div>{{(person$ | async).age}}</div>

alors que le composant constructeur de la classe aurait

export class MyComponent {
  person$: Observable<Person>;

  constructor(
    private store: Store<ApplicationState>
  ) {
      this.person$ = this.store.select(stateToCurrentPersonSelector);
  }
.....
.....
}

Autant je comprends ce code implique 3 abonnements (faites dans le modèle via le async pipe) de la même Observables (person$).

Une autre solution serait de définir 1 propriété (person) dans MyComponent et 1 abonnement (dans le constructeur) qui remplit la propriété, tels que

export class MyComponent {
  person: Person;

  constructor(
    private store: Store<ApplicationState>
  ) {
      this.store.select(stateToCurrentPersonSelector)
                .subscribe(person => this.person = person);
  }
.....
.....
}

bien que le modèle utilise la norme de la propriété de liaison (c'est à dire sans l'async pipe), tels que

<div>{{person.name}}</div>
<div>{{person.address}}</div>
<div>{{person.age}}</div>

Maintenant, la question

Quelle est la différence en termes de performances entre les 2 approches? Est l'utilisation massive de async pipe (c'est à dire une utilisation massive des abonnements) va affecter l'efficacité du code?

45voto

Victor Godoy Points 993

Ni, vous devez composer votre application en tant que smart et les éléments de présentation.

Avantages:

  • Tous les buissness logique sur la puce du contrôleur.
  • Juste un abonnez-vous
  • La réutilisabilité
  • La présentation contrôleur n'a qu'une responsabilité, uniquement pour présenter des données et ne sait pas d'où proviennent les données. (faiblement couplé)

Répondre à la dernière question:

L'utilisation massive de la async tuyau d'influer sur l'efficacité, car il va vous abonner à tous les async pipe. Vous pouvez remarquer ce plus si vous appelez un service http, parce qu'il appellera la requête http pour chaque async pipe.

Composant Intelligent

@Component({
  selector: 'app-my',
  template: `
      <app-person [person]="person$ | async"></app-person>
`,
  styleUrls: ['./my.component.css']
})
export class MyComponent implements OnInit {

    person$: Observable<Person>;

    constructor(private store: Store<ApplicationState>) {}

    ngOnInit() {
        this.person$ = this.store.select(stateToCurrentPersonSelector);
    }

}

Composant De Présentation

@Component({
  selector: 'app-person',
  template: `
    <div>{{person.name}}</div>
    <div>{{person.address}}</div>
    <div>{{person.age}}</div>
`,
  styleUrls: ['./my.component.css']
})
export class PersonComponent implements OnInit {

    @Input() person: Person;

    constructor() {}

    ngOnInit() {
    }

}

Pour plus d'informations, consultez:

19voto

bzykubd Points 469

Une autre possibilité consiste à utiliser une construction comme ceci:

 <div *ngIf="person$ | async as per">
    <div>{{ per.name }}</div>
    <div>{{ per.address }}</div>
    <div>{{ per.age }}</div>
<div>
 

Bien que, pour les morceaux de code réutilisables, il soit préférable d’utiliser la méthode du composant de présentation.

S'il vous plaît noter que cela fonctionne dans 5 angulaire, pas sûr des autres versions.

12voto

John Hamm Points 41

Vous pouvez ajouter ".share ()" à la fin de toute déclaration observable. Tous vos canaux asynchrones sur un observable partageront alors le même abonnement:

 this.name$ = Observable.create(observer => {
  console.log("Subscriber!", observer);
  return observer.next("john")
}).delay(2000).share();

this.httpget$ = http.get("https://api.github.com/").share();
 

Démonstration de Plunkr: https://embed.plnkr.co/HNuq1jUh3vyfR2IuIeeXX/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X