2015-09-16 16 views
6

Ember 2.0 bardzo się starał, aby wszystko było komponentem. Niedługo pojawią się komponenty rutowane, prawdopodobnie również kontrolery zostaną wycofane.Gdzie przechowywać stan przejściowy interfejsu użytkownika w Ember 2.0

Kontekst

Jednak nie jest powracającym problemem zmierzyć podczas tworzenia interfejsu użytkownika, który nie mam satysfakcjonujące wzór do tej pory: stan interfejsu użytkownika.

Co robię?

  • stan Wybór
  • Obecny nacisk
  • Składane/stan rozłożony w jakimś wyświetlaczu drzewa

Zasadniczo każde państwo, które nie jest częścią rzeczywistych danych, ale musi być śledzone na zasadzie osobno dla każdego obiektu. W przeszłości robiono to z Controllers, działając jako proxy dla modeli. Takie podejście jest już przestarzałe. Nowe podejście to Components wszędzie, na lepsze. Component wykonuje księgowość, śledzi stan przejściowy i otrzymujesz akcje z powrotem.

Typowy wzór, jaki mam, jest jednak ze stanem współdzielonym, na przykład lista z elementami do wyboru.

Kwestia

Budowanie składnik List z następującymi wymaganiami:

  • można wybrać każdy element.
  • Stan zaznaczenia zmienia DOM (niektóre powiązania klas).
  • Użytkownik może narysować prostokąt w komponencie listy, aby zaznaczyć kilka pozycji jednocześnie.
  • Idealnie, całe zachowanie może zostać wyabstrahowane jako mixin.

Pytanie: gdzie znajduje się flaga wyboru?

Próby

1) wszystko to jest komponentem.

Każdą pozycję robię jako podkomponent, powiedzmy {{moja-lista-pozycji}}. Komponent śledzi stan zaznaczenia. Problem: w jaki sposób składnik listy może zaktualizować stan zaznaczenia?

2) Przenieś stan z podkomponentów.

Umieść go na komponencie listy. W oddzielnej tablicy stanów obok listy pozycji. Plusy: lista ma cały stan, którego potrzebuje. Wady: to koszmar, aby utrzymać synchronizację, gdy elementy są dodawane lub usuwane z listy. Oznacza to, że podkomponent nie ma dostępu do stanu. A może mógłbym przekazać je jako wartość powiązaną?

3) Ponowne wprowadzenie serwerów proxy.

Pomyśl o tym, jest sposób, aby podzielić się pewnym stanem: umieścić go na modelach.Cóż, nie w rzeczywistych modelach, aby nie zanieczyszczać ich lokalnym stanem, ale poprzez ustawienie ArrayProxy, które zwróci pewną liczbę ObjectProxy dla każdego elementu, aby utrzymać stan.

Zalety: to jedyne rozwiązanie, które udało mi się całkowicie wdrożyć. Minusy: enkapsulacja i dekapitacja przedmiotów to kłopot. Ponadto po kilku warstwach przekazu, get i set muszą przejść przez 4 ou 5 serwerów proxy, które, jak się obawiam, będą stanowić problem z wydajnością.

Ponadto nie działa dobrze w przypadku miksów. Czy chcę wyodrębnić niektóre mixy HasSelection i mixin HasFoldableItems i mixin Sortable, wszystkie one potrzebują jakiegoś stanu.

Powrót do deski kreślarskiej

Czy jest jakiś lepszy wzorzec nie znalazłem?

znalazłem następujące istotne pytania, ale to doprowadziło mnie nigdzie:

+1

Toran jest na dobrej drodze, gdy stan staje się zbyt skomplikowany, by poszczególne elementy mogły być zarządzane, wyciągnij stan z interfejsu i włącz go do serwisu. Napisałem komentarz na ten temat tutaj: http://www.samselikoff.com/blog/comment-on-data-flow-in-ember-apps/ –

Odpowiedz

7

Świetne pytanie - rzeczywiście poszedłem do jednego z członków głównego zespołu Ember, aby dowiedzieć się, a odpowiedź brzmi obecnie usługi. Ponieważ składnik najlepiej pozostawić bezstanowy (w przeważającej części) można wykorzystać usługę do utrzymania tego stanu, który nie pasuje do modelu utrwalonego na serwerze.

Tutaj jest doskonałym przykładem, że Stef Penner ułożyła pokazując jak można zapisać projekt „e-mail” w aplikacji ember (to nie jest utrwalane backend)

https://github.com/stefanpenner/ember-state-services

Przykład elementem odniesienia (z powyższego projektu github)

export default Ember.Component.extend({ 
    tagName: 'form', 
    editEmailService: Ember.inject.service('email-edit'), 
    state: Ember.computed('email', function() { 
    return this.editEmailService.stateFor(this.get('email')); 
    }).readOnly(), 

    actions: { 
    save() { 
     this.get('state').applyChanges(); 
     this.sendAction('on-save', this.get('email')); 
    }, 

    cancel() { 
     this.get('state').discardChanges(); 
     this.sendAction('on-cancel', this.get('email')); 
    } 
    } 
}); 
+0

Czytanie rzeczy usług państwowych już teraz. Takie podejście wygląda bardzo dobrze, w zasadzie komponenty będą współdzielić stan, gdy użyją tego samego "stateName". Jednak wydaje się, że parametr stateName musi być predefiniowany, co oznacza, że ​​wszystkie wystąpienia tego samego komponentu będą współużytkować ten sam stan. Ale widzę, jak można dodać poziom pośredni (tylko jedna usługa może tworzyć nowe nazwy w locie). To podejście jest lepsze niż wszystkie trzy, które miałem w swoim pytaniu. Chciałbym jednak pozostawić pytanie otwarte na jakiś czas, aby sprawdzić, czy inni się pojawią. – spectras

+0

W porządku. Spiczasty moduł ma bardzo dobrą koncepcję. To powinno naprawdę pójść gdzieś w samouczku ember.js. Nie w pełni pasuje do przypadku użycia, ponieważ jest ukierunkowany na długoterminowy stan interfejsu użytkownika, który nie wymaga zarządzania cyklem życia, ale mógłbym oprzeć się na pomyśle: Zrobiłem magazyn stanu jako obiekt, który komponent macierzysty wstrzykuje (przez attr) do podskładników. ** Minusy **: już nie singleton, więc może trochę to psuje. ** Plusy **: mogę połączyć czas życia komponentu i stanu, co ma sens tutaj. – spectras

+0

@spectras Czy masz szansę na osobne rozwiązanie? – Jon

Powiązane problemy