2017-01-17 7 views
20

Zaczynam patrzeć na Ngrx Store i widzę wygodę użycia rurki asynchronicznej Angular. W tym samym czasie nie jestem pewien, czy użycie masywnej rury asynchronicznej jest dobrym wyborem.NgrxStore i Angular - Użyj rury asynchronicznej masowo lub zasubskrybuj tylko raz w konstruktorze.

Podam prosty przykład. Załóżmy, że w tym samym szablonie muszę pokazać różne atrybuty obiektu (np. Osoby), które są pobierane ze Sklepu.

kawałek kodu szablonu może być

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

podczas gdy konstruktor klasy komponent miałby

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

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

O ile mi zrozumieć ten kod oznacza 3 subskrypcje (wykonane w szablonie za pomocą async pipe) do tego samego Observable (person$).

Alternatywą byłoby określenie 1 właściwość (person) w MyComponent i mają tylko jeden zapis (w konstruktora), która wypełnia właściwości, takie jak

export class MyComponent { 
    person: Person; 

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

gdy szablon wykorzystuje standardowe wiązania właściwość (to znaczy bez rury asynchronicznej), takie jak

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

się pytanie

Czy między dwoma podejściami występuje różnica w wydajności? Czy masowe użycie asynchronicznej rury (tj. Masowe wykorzystanie subskrypcji) wpłynie na wydajność kodu?

Dzięki jest z góry za wszelkie wytyczne

+2

Możesz rozważyć użycie rury asynchronicznej w kontenerach na wejściach dla "głupich" komponentów. Zobacz komponenty i kontenery w [przykładowej aplikacji] (https://github.com/ngrx/example-app/tree/master/src/app), a także [* Elementy prezentacji i kontenera *] (https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0). – cartant

Odpowiedz

20

Ani należy komponować swoją aplikację komponenty jak inteligentne i prezentacji.

Zalety:

  • Wszystko logika buissness na inteligentnego sterownika.
  • Tylko jeden subskrybować
  • Ponowne
  • Kontroler prezentacja ma tylko jeden obowiązek, tylko do przedstawienia danych i nie wie, skąd pochodzą dane. (Luźno)

Odbieranie ostatnie pytanie

masowe wykorzystanie rur asynchronicznym wpływa na wydajność, ponieważ subskrybować każdej rury asynchronicznym. Możesz to zauważyć bardziej, jeśli wywołujesz usługę http, ponieważ wywoła ona żądanie http dla każdej rury asynchronicznej.

Inteligentne Komponent

@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); 
    } 

} 

Prezentacja Komponent

@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() { 
    } 

} 

Aby uzyskać więcej informacji należy sprawdzić:

+0

Doceniam wartość dzielenia elementów inteligentnych i prezentacji. Ma to wiele sensu ze wszystkich powodów, o których wspomniałeś. Jeśli spojrzymy tylko na stronę "skuteczności kodu", czy mam rację zakładając, że używanie jednej "rury asynchronicznej" i wielu "powiązań własności" jest bardziej wydajne niż użycie "wielu rur asynchronicznych"? Thx z góry – Picci

+1

@Picci aktualizuję odpowiedź –

+0

dobre pytanie i odpowiedź! dzięki za linki szczególnie! –

6

Możesz dodać ".share()" na końcu wszelkich deklarowalnych deklaracji. Wszystkich swoich rur asynchronicznych na zauważalny będzie wtedy podziela tą subskrypcję:

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 wykazanie,: https://embed.plnkr.co/HNuq1jUh3vyfR2IuIe4X/

3

Inną możliwością jest użycie budowę tak:

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

Chociaż do wielokrotnego użytku bitów kodu jego lepiej jest użyć metody komponentu prezentacji.

Pamiętaj, że działa to w kanciastym 5, nie jesteś pewien innych wersji.

+0

Podoba mi się to, ponieważ łączy inteligentne i prezentacyjne komponenty w jednym bloku kodu. Nie podoba mi się to z dokładnie tego samego powodu. :) – JoshuaTree