Je commence à regarder ngrx Store et je vois la commodité d'utiliser le canal asynchrone Angular. En même temps, je ne suis pas sûr d'utiliser le Angular le tuyau asynchrone est massivement un bon choix.
Je fais un exemple simple. Supposons que dans le même modèle, je dois montrer différents attributs d'un objet (par exemple, une personne) qui est récupéré à partir du magasin.
Un morceau de code de modèle pourrait être
<div>{{(person$ | async).name}}</div>
<div>{{(person$ | async).address}}</div>
<div>{{(person$ | async).age}}</div>
tandis que le constructeur de classe de composant aurait
export class MyComponent {
person$: Observable<Person>;
constructor(
private store: Store<ApplicationState>
) {
this.person$ = this.store.select(stateToCurrentPersonSelector);
}
.....
.....
}
Pour autant que je comprends ce code implique 3 abonnements (effectués dans le modèle via le canal asynchrone) au même observable (person$
).
Une alternative serait de définir 1 propriété (person
) dans MyComponent et d'avoir seulement 1 abonnement (dans le constructeur) qui remplit la propriété, comme
export class MyComponent {
person: Person;
constructor(
private store: Store<ApplicationState>
) {
this.store.select(stateToCurrentPersonSelector)
.subscribe(person => this.person = person);
}
.....
.....
}
tandis que le modèle utilise la liaison de propriété standard (c'est-à-dire sans le canal asynchrone), comme
<div>{{person.name}}</div>
<div>{{person.address}}</div>
<div>{{person.age}}</div>
Maintenant la question
Y a-t-il une différence en termes de performances entre les 2 approches? L'utilisation massive du canal asynchrone (c'est-à-dire une utilisation massive des abonnements) va-t-elle affecter l'efficacité du code?
Vous ne devez pas non plus composer votre application en tant que composants intelligents et de présentation.
Avantages:
Répondre à la dernière question:
L'utilisation massive du canal asynchrone affectera l'efficacité, car il s'abonnera à chaque canal asynchrone. Vous pouvez le remarquer davantage si vous appelez un service http, car il appellera la demande http pour chaque canal asynchrone.
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:
Une autre possibilité consiste à utiliser une construction comme celle-ci:
<div *ngIf="person$ | async as per">
<div>{{ per.name }}</div>
<div>{{ per.address }}</div>
<div>{{ per.age }}</div>
<div>
Bien que pour les bits de code réutilisables, il est préférable d'utiliser la méthode du composant de présentation.
Veuillez noter que cela fonctionne en angular 5, pas sûr des autres versions.
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();
Plunkr démontrant: https://embed.plnkr.co/HNuq1jUh3vyfR2IuIe4X/