8 najczęstszych błędów popełnianych przez programistów Backbone.js
Opublikowany: 2022-03-11Backbone.js to minimalistyczny framework, którego celem jest dostarczenie prostego zestawu struktur danych i funkcji, których można użyć do stworzenia interfejsu użytkownika ustrukturyzowanej aplikacji internetowej. Po wyjęciu z pudełka komponenty Backbone.js zapewniają intuicyjne środowisko, które możesz już znać podczas pracy z modelami i widokami na zapleczu. Modele i kolekcje w Backbone.js są proste, ale mają kilka bardzo przydatnych funkcji, takich jak możliwość łatwej integracji z interfejsami API REST JSON. Ale są również wystarczająco elastyczne, aby można je było dostosować do niemal każdego praktycznego zastosowania.
W tym samouczku Backbone.js przyjrzymy się niektórym typowym błędom, które często popełniają niezależni programiści, którzy po raz pierwszy próbują nauczyć się Backbone.js, oraz sposobom ich uniknięcia.
Błąd nr 1: ignorowanie arsenału funkcjonalności Backbone.js
Backbone.js może być minimalistycznym frameworkiem, ale (wraz z Underscore.js) zapewnia mnóstwo funkcji i funkcji, które mogą z łatwością zaspokoić najbardziej podstawowe i niektóre z kluczowych potrzeb, które pojawiają się podczas tworzenia nowoczesnej aplikacji internetowej. Częstym błędem, który często popełniają początkujący programiści, jest to, że traktują Backbone.js jako kolejny framework kliencki podobny do MVC dla sieci. Chociaż ta sekcja mówi o czymś bardzo oczywistym, jeśli chodzi o Backbone.js, bardzo krytycznym błędem jest niedokładne zbadanie frameworka. Framework może być niewielki, ale to właśnie czyni go doskonałym kandydatem do tej gruntownej eksploracji. Zwłaszcza jego mały i ładnie opatrzony adnotacjami kod źródłowy.
Backbone.js zapewnia absolutne minimum wymagane do nadania aplikacji internetowej struktury, z której może czerpać korzyści. Dzięki swojej rozszerzalności i mnóstwu wtyczek, nauka Backbone.js może być wykorzystana do tworzenia niesamowitych aplikacji internetowych. Niektóre z najbardziej oczywistych cech Backbone.js są ujawniane przez modele, kolekcje i widoki. Komponenty routera i historii zapewniają prosty, ale elegancki mechanizm do obsługi routingu po stronie klienta. Chociaż Underscore.js jest zależnością Backbone.js, jest całkiem dobrze zintegrowany z frameworkiem, ponieważ zarówno modele, jak i kolekcje wiele korzystają z tego niesamowitego paska narzędzi dla JavaScript, a także są dostępne do Twojej dyspozycji.
Kod źródłowy frameworka jest tak dobrze napisany i opatrzony adnotacjami, że prawdopodobnie można by go przeczytać przy filiżance kawy. Początkujący mogą wiele skorzystać z czytania adnotacji źródłowych, ponieważ mogą się wiele dowiedzieć o tym, jak framework działa wewnętrznie, a także zastosować zgrabny zestaw najlepszych praktyk, jeśli chodzi o JavaScript.
Błąd nr 2: Modyfikowanie DOM w bezpośredniej reakcji na zdarzenia arbitralne
Coś, co zwykle robimy, kiedy zaczynamy uczyć się Backbone.js, to nie robić rzeczy zgodnie z zaleceniami Backbone.js. Na przykład mamy tendencję do obsługi zdarzeń i przeglądania aktualizacji w sposób, w jaki robilibyśmy to za pomocą jQuery na prostych stronach internetowych. Backbone.js ma na celu nadanie Twojej aplikacji internetowej sztywnej struktury poprzez odpowiednie oddzielenie problemów. To, co często robimy z Backbone.js, to aktualizowanie widoku w odpowiedzi na dowolne zdarzenia DOM:
var AudioPlayerControls = Backbone.View.extend({ events: { 'click .btn-play, .btn-pause': function(event) { $(event.target).toggleClass('btn-play btn-pause') } }, // ... })Za wszelką cenę należy tego unikać. Być może uda się wymyślić niejasne przykłady, w których może to mieć sens; ale w większości przypadków są na to znacznie lepsze sposoby. W rzeczywistości jednym ze sposobów, który mógłbym tutaj podać, jest użycie modelu do śledzenia stanu odtwarzacza audio i wykorzystanie informacji o stanie do renderowania przycisku (a dokładniej jego nazw klas):
var AudioPlayerControls = Backbone.View.extend({ events: { 'click .btn-play, .btn-pause': function(event) { this.model.set('playing', !this.model.get('playing')) } }, initialize: function() { this.listenTo(this.model, 'change', this.render) this.render() }, // ... }) <button class=”btn btn-<%- playing ? 'pause' : 'play' %>”></button>Mogą wystąpić rzadkie sytuacje, w których bezpośrednia manipulacja DOM z programów obsługi zdarzeń będzie miała sens, ale koszt związany z zarządzaniem złożonymi manipulacjami DOM z programów obsługi zdarzeń prawie nigdy nie jest tego wart. To jest coś, co Backbone.js ma rozwiązać. Używanie Backbone.js do robienia czegoś takiego jest błędem.
Błąd nr 3: Niedocenianie kosztów renderowania
Ponieważ Backbone.js bardzo ułatwia renderowanie i ponowne renderowanie DOM do woli lub w odpowiedzi na zdarzenia, często przeoczamy, jak duży wpływ ma to na ogólną wydajność aplikacji internetowej. Istnieje wiele sposobów, w jakie możemy zakończyć metodę renderowania w naszych widokach. Często wydaje się, że to niewiele, ponieważ nowoczesne przeglądarki internetowe stają się wysoce wydajnym oprogramowaniem. Jednak wraz ze wzrostem aplikacji internetowej i ilości danych, którymi się zajmuje, spadek wydajności staje się coraz bardziej widoczny.
Możemy to zobaczyć w akcji na wymyślonym przykładzie, w którym zaczynamy od małej kolekcji modeli i renderujemy to w widoku listy:
var AudioPlayerPlaylist = Backbone.View.extend({ template: _.template('<ul> <% _.each(musics, function(m) { %> <li><%- m.title %></li> <% }) %> </ul>'), initialize: function() { this.listenTo(this.collection, 'add', this.render) }, // ... })W tym przykładzie Backbone.js renderujemy ponownie za każdym razem, gdy model jest dodawany do kolekcji. To zadziała dobrze. Ponieważ jednak zdarzenie „dodaj” jest uruchamiane za każdym razem, gdy model jest dodawany do listy, wyobraź sobie pobranie dużej listy modeli z serwera. Metoda render będzie wywoływana wiele razy z rzędu, raz dla każdego modelu w odpowiedzi z serwera. Wystarczająco duży model wystarczy, aby aplikacja zacinała się i zrujnowała wrażenia użytkownika. Czasami wystarczy mała odpowiedź, w zależności od złożoności renderowanego widoku.
Bardzo szybkim rozwiązaniem tego problemu jest po prostu nie wywoływanie metody render dla każdego dodawanego modelu. W takich sytuacjach modele będą dodawane wsadowo i faktycznie możesz zrobić coś, aby metoda render była uruchamiana tylko wtedy, gdy zostanie wywołana, ale nie zostanie ponownie wywołana w określonym czasie. Zależność Backbone.js Underscore.js zawiera przydatną funkcję użytkową do tego celu: „_.debounce”. Wszystko, co musisz z tego skorzystać, to zmienić linię JavaScript wiążącą zdarzenie za pomocą tego:
this.listenTo(this.collection, 'add', _.debounce(_.bind(this.render), 128))Spowoduje to, że wywołanie zwrotne zdarzenia będzie uruchamiane za każdym razem, gdy wystąpi zdarzenie „add”, jednak poczeka 128 milisekund od ostatniego zdarzenia przed faktycznym wywołaniem metody render.
W większości przypadków będzie to uważane za szybkie rozwiązanie. W rzeczywistości istnieją bardziej odpowiednie sposoby na uniknięcie thrashingu renderowania. Deweloperzy stojący za Trello napisali kiedyś post na blogu, omawiając swoje doświadczenie i podejście do poprawy wydajności renderowania podczas korzystania z Backbone.js.
Błąd nr 4: pozostawienie słuchaczy zdarzeń poza ich wykorzystaniem
Pozostawienie nieużywanych detektorów zdarzeń związanych jest prawdopodobnie czymś, co może się zdarzyć niezależnie od tego, jakiego frameworka JavaScript używasz, lub jeśli w ogóle używasz któregoś. Mimo, że Backbone.js ułatwia uniknięcie tego problemu, z pewnością błędem jest pozostawianie potencjalnych dziur dla łatwych wycieków pamięci w Twojej aplikacji internetowej. Komponent „Event” Backbone.js to z pewnością całkiem zgrabna implementacja. Pozwala obiektom JavaScript na łatwe wdrażanie funkcji opartych na zdarzeniach. Ponieważ wyświetlenia są miejscem, w którym zwykle ma miejsce większość naszych zdarzeń, łatwo jest popełnić ten błąd:
var AudioPlayerControl = Backbone.View.extend({ initialize: function() { this.model.on('change', _.bind(this.render, this)) // ... }, // ... })Wiersz powiązania zdarzenia w tym fragmencie kodu nie różni się zbytnio od wiersza w pierwszym przykładzie. Jedyne, co tutaj zrobiliśmy, to zmiana „tego.listenTo(ten.model,…)” na „ten.model.on(…)”. Ponieważ jesteśmy bardzo przyzwyczajeni do wywołania „.on()” do wiązania zdarzeń z naszego doświadczenia z niektórymi innymi frameworkami i bibliotekami JavaScript, kiedy zaczynamy używać Backbone.js, często używamy wywołań „.on()” do wiązania wydarzenia. Byłoby to w porządku, tylko gdybyśmy zawracali sobie głowę wywołaniem „.off()” w celu usunięcia powiązań obsługi zdarzeń, gdy nie są już potrzebne. Ale rzadko to robimy i kończy się to źródłem wycieków pamięci.

Backbone.js oferuje prosty sposób na rozwiązanie tego problemu. Dzieje się tak za pomocą metody „object.listenTo()”. Dzięki temu obiekt, który wywołujesz „listenTo()”, może śledzić zdarzenia, których nasłuchuje, a także ułatwia jednoczesne usuwanie wszystkich tych zdarzeń. Na przykład widoki automatycznie przestają słuchać wszystkich powiązanych zdarzeń, gdy tylko wywołasz na nich „remove()”.
Błąd nr 5: Tworzenie widoków monolitycznych
Jeśli się nad tym zastanowić, minimalizm Backbone.js zapewnia ogromną elastyczność w zakresie projektowania interfejsu użytkownika aplikacji internetowej. Ponieważ modele, kolekcje i widoki są elementami składowymi Twoich komponentów, ważne jest, aby były one jak najlżejsze i jak najbardziej szczegółowe. Najczęściej to widoki stają się najcięższym aspektem Twojej aplikacji internetowej pod względem kodu. Ale naprawdę ważne jest, aby nie tworzyć gigantycznych monolitycznych widoków, które w końcu próbują zrobić wszystko, co ma do zaoferowania Twoja aplikacja. Zamiast tworzyć gigantyczny widok „AudioPlayer” z całą logiką, podziel go na kilka logicznych widoków, takich jak widok listy odtwarzania, widok elementów sterujących, widok wizualizatora i tak dalej. Jaki rodzaj szczegółowości chcesz zapewnić, prawdopodobnie zależy od aplikacji, którą próbujesz zbudować.
Dzieje się tak, ponieważ w przypadku widoków granularnych, w których każdy widok robi coś konkretnego i robi to dobrze, tworzenie aplikacji internetowej za pomocą Backbone.js staje się dziecinnie proste. Twój kod powinien być łatwiejszy w utrzymaniu i łatwy do rozszerzania lub modyfikowania w przyszłości. Jest też druga skrajność, w której przesadzasz. Widoki Backbone.js są zaprojektowane tak, aby ułatwić Ci pracę z modelem lub kolekcją, a to prawdopodobnie może działać jako wskazówka, jak powinieneś ustrukturyzować swoją aplikację. Ian Storm Taylor podzielił się na swoim blogu kilkoma cennymi pomysłami, o których prawdopodobnie powinieneś pamiętać podczas wdrażania poglądów.
Błąd nr 6: Nie zdajemy sobie sprawy, że Backbone.js można dostosować do interfejsów API innych niż REST
Backbone.js działa od razu z interfejsami API RESTful opartymi na JSON. Wszystko, czego potrzebujesz do tego, to jQuery (lub coś, co może go zastąpić, np. Zepto). Backbone.js jest jednak niezwykle rozszerzalny. W rzeczywistości Backbone.js można dostosować do korzystania z innych typów interfejsów API, a nawet innych formatów kodowania.
Komponentem Backbone.js, który zajmuje się interakcją front-endu z usługami back-endu, jest „Sync”. Ten składnik udostępnia szereg atrybutów, które można łatwo przesłonić, aby dostosować sposób interakcji Backbone.js z punktami końcowymi interfejsu API. W rzeczywistości możliwe jest również zastąpienie domyślnego mechanizmu synchronizacji czymś, co nie jest tak tradycyjne, jak choćby używanie localStorage do utrwalania danych zamiast usług zaplecza.
Istnieje wiele wtyczek, które ułatwiają dostosowanie zachowania synchronizacji Backbone.js. Na przykład wtyczka o nazwie Backbone.dualStorage umożliwia używanie zarówno usług zaplecza, jak i localStorage do utrwalania danych. Gdy aplikacja przechodzi w tryb offline, wtyczka używa localStorage do obsługi żądań z danych z pamięci podręcznej i śledzenia zmian, które możesz później zsynchronizować z serwerem, gdy będziesz online.
Chociaż używanie Backbone.js z back-endem zaprojektowanym jako RESTful i zgodnym z nim jest łatwiejsze w użyciu, nie oznacza to, że jest to wszystko, z czym Backbone.js może współpracować. Po wprowadzeniu pewnych zmian w domyślnym mechanizmie synchronizacji Backbone.js można dostosować go do szerokiej gamy interfejsów API usług zaplecza i formatów kodowania.
Warto wspomnieć, że inne części Backbone.js są również elastyczne iw pewien sposób opcjonalne. Na przykład nie musisz używać domyślnego silnika szablonów, który jest dostarczany z Underscore.js. Nie musisz nawet używać komponentu widoku Backbone.js i możesz go zastąpić czymś zupełnie innym, jeśli chcesz.
Błąd 7: Przechowywanie danych w widokach zamiast w modelach
Jednym z błędów, który często popełniamy jako początkujący uczący się Backbone.js, jest przechowywanie danych bezpośrednio w widokach jako atrybuty. Te dane mogą być dostępne w celu śledzenia pewnego stanu lub wyboru użytkownika. To jest coś, czego należy unikać.
var AudioPlayerVisualizer = Backbone.View.extend({ events: { 'click .btn-color': function(event) { this.colorHex = $(event.target).data('color-hex') this.render() } }, // ... })Zawsze możesz stworzyć dodatkowe modele i kolekcje bez punktów końcowych. Mogą one pomóc w przechowywaniu danych, które niekoniecznie muszą być utrwalane na zapleczu lub mogą mieć charakter tymczasowy. Przechowywanie ich w modelach daje możliwość nasłuchiwania zmian. Odpowiedni widok, a nawet wiele widoków, może obserwować te modele i ponownie renderować się w razie potrzeby.
Wyobraź sobie, że faktycznie przechowujesz zmienne śledzenia stanu w widokach i musisz wywoływać metodę render za każdym razem, gdy je zmieniasz. Brakujące tylko jedno wywołanie tej metody renderowania może pozostawić aplikację w stanie niesprawnym pod względem tego, czego doświadcza użytkownik na ekranie. Co więcej, w przypadku małych widoków może być konieczne zsynchronizowanie tych zmiennych stanu na wielu obiektach widoku, a następnie wywołanie na nich również metody render.
Błąd nr 8: Używanie jQuery „.on()” zamiast delegowanych zdarzeń
Backbone.js ma moim zdaniem jeden wspaniały sposób obsługi zdarzeń DOM. Nieużywanie go ma wiele wad. Funkcja wiązania zdarzeń „.on()” w jQuery może wydawać się wygodna, ale często okazuje się kłopotliwa na dłuższą metę. Na przykład, gdy elementy są odłączone od DOM, jQuery automatycznie usuwa wszystkie programy obsługi zdarzeń powiązane z elementami za pomocą „.on()”. Oznacza to, że każde zdarzenie DOM, z którym próbujesz się powiązać z poziomu widoku, będzie musiało zostać odtworzone, jeśli odłączysz element główny od DOM i ponownie go dołączysz.
var AudioPlayerControls = Backbone.View.extend({ events: { 'click .btn-play, .btn-pause': function() { /* ... */ }, 'click .btn-prev': function() { /* ... */ }, 'click .btn-next': function() { /* ... */ }, 'click .btn-shuffle': function() { /* ... */ }, 'click .btn-repeat': function() { /* ... */ } }, // ... })Gdy element odpowiadający temu widokowi zostanie ponownie dołączony do DOM, wystarczy wywołać „delegateEvents()” w widoku, aby powiązać wszystkie te zdarzenia.
Pamiętaj, że ważne jest, aby zrozumieć, w jaki sposób te wydarzenia są powiązane. Zamiast wiązania zdarzenia z elementami określonymi przez selektor, Backbone.js faktycznie wiąże procedurę obsługi zdarzeń z elementem głównym widoku. Działa to dobrze w prawie wszystkich przypadkach i faktycznie działa lepiej dla większości naszych potrzeb. Zmiana lub zastąpienie elementów podrzędnych w poddrzewie DOM widoku nie wymaga, aby Backbone.js ponownie powiązał każde zdarzenie z nowymi elementami. Obecni słuchacze po prostu pracują.
Zapobiega to jednak odsłuchiwaniu niektórych zdarzeń. Jednym z przykładów jest sytuacja, w której możesz chcieć nasłuchiwać zdarzeń przewijania w „oknie” lub na przewijanym elemencie podrzędnym. W przypadku elementów potomnych, możesz stworzyć podwidok dla tego elementu i obsłużyć tam zdarzenia.
Wniosek
Backbone.js, będąc bardzo kompaktowym, ale rozszerzalnym frameworkiem, jest doskonałym wyborem dla aplikacji internetowych, które wymagają dużej elastyczności za kulisami. W przeciwieństwie do frameworków, takich jak Angular.js i Ember.js, które zawsze podpowiadają Ci, jak robić to, co chcesz, Backbone.js robi krok w tył, daje potężny zestaw narzędzi i pozwala zdecydować, jak używać ich. Mam nadzieję, że ten samouczek Backbone.js dla początkujących pomoże ci uniknąć niektórych typowych błędów programistycznych i zbudować z nim coś niesamowitego.
