2013-03-21 7 views
15

Z mojego zrozumienia atrybuty modelu backbone.js mają być zadeklarowane jako nieco prywatnych zmiennych składowych mówiącbackbone.js dostęp do atrybutów modelu w modelu - this.attribute VS this.get ("atrybut")?

this.set({ attributeName: attributeValue }) 
// accessing the value 
this.get('attributeName'); 

Ale gdy piszę funkcje wzięciu rzeczywisty model wydaje się znacznie prostsze powiedzieć, jak to :

this.attributeName = attributeValue; 
// accessing the value 
this.attributeName; 

Zakładam też, że ta druga wersja będzie szybciej przetwarzana, ponieważ nie przechodzi przez zarządzanie zdarzeniami backbone.js.

Więc zastanawiałem się, jak radzicie sobie z zaletami, które są używane przede wszystkim wewnętrznie w modelu. Są to atrybuty, które faktycznie chcieliby być nieco osłonięte od zewnątrz, więc wystawienie ich tak, jak w tym ostatnim przykładzie, może nie jest prawidłowe. Kiedy przeglądam przykłady dla widoku backbone.js, który nie ma metod pobierania i ustawiania, wydaje się, że dobrze jest zrobić to w drugim przykładzie. Czy istnieje jakaś dobra zasada, kiedy używać get/set (atrybut) lub this.attribute podczas kodowania w modelu? A może przykład modelu, który czyni to wyraźniejszym?

+0

dlaczego chcesz uniknąć zarządzanie zdarzeniami szkieletowej? mogą tam być widoki, które nasłuchują pewnych atrybutów, niezależnie od tego, czy są one aktualizowane wewnątrz czy na zewnątrz kręgosłupa.Model? – neebz

+1

Po prostu myślałem, że kiedy na przykład w mojej aplikacji aktualizuję niektóre atrybuty modelu co 16 milisekundów, nie byłoby dobrym pomysłem, aby za każdym razem uruchamiać te wszystkie zdarzenia? Większość przykładów, z którymi się zetknąłem, dotyczy list rzeczy do zrobienia i innych rzeczy, które nie aktualizują się tak często. – torno

+2

Dla prywatnych danych modelu po prostu wpisuję 'this._propName', zamiast umieszczać je w zarządzanym obszarze obiektu' Modelu szkieletowego '. – WiredPrairie

Odpowiedz

54

Kiedy używać model.get(property) i model.set(...)

Należy użyć get i set dostęp do danych modelki. Oznacza to wszelkie atrybuty, które są częścią serializowanej reprezentacji modelu, która jest pobierana za pomocą fetch i zachowywana przy użyciu save.

Kiedy używać model.attributes.property

Nigdy.

Zawsze należy użyć get, a zwłaszcza set zamiast dostępu do obiektu model.attributes bezpośrednio, chociaż widziałem sprzeczne opinie na ten temat. Wydaje mi się, że istnieje umowa pomiędzy model a jej konsumentami, która gwarantuje, że konsument może zostać powiadomiony o wszelkich zmianach danych modelu za pomocą zdarzenia change. Jeśli bezpośrednio modyfikujesz obiekt atrybutów wewnętrznych, zdarzenia nie są wysyłane, a umowa jest zepsuta. Zdarzenia szkieletowe są bardzo szybkie, szczególnie jeśli nie masz podłączonych żadnych detektorów i nie jest to kwestia korzystna z nadmiernej optymalizacji z Twojej strony.

Chociaż dostęp do atrybutów bezpośrednio zamiast get jest zupełnie nieszkodliwy, należy go unikać, więc obiekt attributes można uznać za całkowicie prywatny.

Jeśli konieczne jest zapobieganie niektórym zdarzeniom powodującym zmianę, można użyć opcji silent:true: model.set({key:val}, {silent:true}). To łamie wspomnianą umowę, a nawet kręgosłup własna dokumentacja daje następujące zastrzeżenie:

pamiętać, że jest to rzadko, a może nawet nigdy, to dobry pomysł. Przejście przez konkretną flagę w opcjach wywołania zwrotnego zdarzenia, które można przeglądać i zignorować, zwykle będzie działać lepiej.

Kiedy stosować model.property

żadnych właściwości, które nie są danych, to tymczasowe zmienne, obliczoną Właściwości itd mogą być dołączone bezpośrednio do jednostki modelu. Te właściwości powinny być uważane za tymczasowe i przechodnie: można je odtworzyć po inicjacji modelu lub w trakcie jego trwania, ale nie powinny one być utrzymywane, zarówno publiczne, jak i prywatne. Typowa konwencja nazewnictwa jest prefiks własności prywatnej z charakterem _ następująco:

this._privateProperty = 'foo'; 
this.publicProperty = 'bar'; 
+0

Odpowiedź Nigdy nie można zasugerować początkującym. Ale jeśli kiedykolwiek pracujesz nad bardziej złożonym projektem, który działa z większymi zbiorami danych, absolutnie MUSISZ pracować z modelem.attributes, ponieważ jest on o wiele szybszy niż użycie metod set/get z ich obciążeniem. –

+0

@jiri możesz to udowodnić, wykonując kilka perfekcyjnych testów? – backdesk

2

Nigdy nie jest niekompletna odpowiedź.

Czasami chcesz uzyskać dostęp do kolekcji atrybutów modelu - bez względu na te atrybuty. Rozważmy metodę użytkowego do wykonywania Calcs atrybutów, formatować je do wyjścia, itp

Wygodnym sposobem, aby to zrobić, to aby uzyskać dostęp model.attributes

rozważyć jedną alternatywę, poniżej:

var attributesNames = ['foo', 'bar', 'baz']; 
var attributes = _(attributesNames).map(function(attr) { return model.get(attr); }); 

callSomeUtilityMethod(attributes); 

Dwa problemy:

  • Wprowadziliśmy sprzężenie w kolekcji "attributeNames". Co się stanie, jeśli lista się zmieni?
  • Straciliśmy powiązanie nazwy/wartości. Możemy przepisać powyższą mapę, ale będzie to więcej pracy.

W tym scenariuszu, to znacznie wygodniejsze zrobić coś takiego:

callSomeUtilityMethod(model.attributes); 
+2

Nie polecałbym tego. Nie tylko ujawniasz wewnętrzne atrybuty, ale wystawiasz je na inną metodę, która może nie wiedzieć, że reprezentuje wewnętrzny stan modelu. Jeśli metoda 'callSomeUtilityMethod' modyfikuje obiekt, który otrzymuje jako argument, to (przypadkowo) modyfikuje również stan modelu. W tym przypadku użyłbym metody 'callSomeUtilityMethod (model.toJSON());', która skutecznie klonuje atrybuty modelu i unika problemów, które są trudne do debugowania. – jevakallio

+0

@jevakallio dobrze, gdy model zawiera tylko prymitywy. Nie jest tak dobrze, gdy twój model zawiera obiekty, które możesz chcieć zmienić w jakiejkolwiek funkcji, z której korzystasz. –

+0

BTW: Uważam to za cechę, a nie błąd. Zastanówmy się nad emptorem (stąd "Nigdy nie jest niekompletny"). Potencjalnie poważniejszym problemem jest sytuacja, w której nadpisałeś model get(), aby wykonać jakąś sprytną "magię", którą robię przez cały czas. –