Статьи

Анатомия JavaScript MV * Framework

Ключ к быстрому изучению JavaScript MV * Frameworks состоит в том, чтобы разбить их на ряд функций. Основными функциями приложения MV * являются маршрутизация, привязка данных, шаблоны / представления, модели и доступ к данным. В этой статье я опишу эти функции и покажу примеры кода из AngularJS, Backbone и Ember для каждой функции. Вы начнете конкретно понимать, что эти структуры пытаются помочь вам достичь, и осознаете, что они больше похожи, чем отличаются. Фактически становится очевидным, что большинство структур в значительной степени заимствуют успехи других.

Не беспокойтесь о понимании каждой строки кода. А пока попробуйте оценить, насколько они похожи и какие проблемы они могут решить для вашего проекта.

Маршрутизация

Маршрутизация, как минимум, сопоставляет ваши URL-адреса с функцией, но иногда идет даже до реализации полного шаблона проектирования «конечного автомата» для управления переходами состояний в представлении. Если вы когда-либо использовали маршрутизатор в серверной инфраструктуре MVC, такой как Rails, CodeIgniter, CakePHP, ASP.NET MVC и т. Д., То вы можете просто думать о маршрутизаторах JavaScript MV * как об одном и том же, но работающих на клиент в JavaScript.

Вам может быть интересно, как это работает, и будет ли это работать на старых браузерах? Однако все, что находится после хеш-тега в URL-адресе, считается маршрутом, если настроена поддержка push-состояний HTML (с одной строкой кода в большинстве сред), тогда URL-адреса без хэшей, соответствующие маршрутам, будут перехвачены на клиенте и будут выполняться JavaScript также.

Достаточно подробностей, давайте посмотрим код.

Пример магистрали

Вот простой пример маршрутизации в Backbone.js:

Обратите внимание на объект AppRouter Маршруты сопоставлены с функциями. Функции просто создают объект представления, который управляет фрагментом DOM и добавляет его на страницу при изменении URL. Backbone.history.start()

Пример AngularJS

Вот простой пример маршрутизации в AngularJS:

Пример AngularJS очень похож на пример Backbone, за исключением того, что маршруты отображаются на templateUrl

Пример Ember

Ниже приведен простой пример маршрутизации в Ember:

Опять же, очень похоже на другие, за исключением того, что для Ember.js первым параметром объекта «маршрутизатора» является routeName Порядок этих параметров сначала смутил меня, пока кто-то не указал, что параметр path является необязательным и часто может быть установлен соглашением, как это происходит со страницей about в примере. Кроме того, шаблоны Ember необходимы для работы этого простого примера маршрутизации, но я рассмотрю их в следующем разделе. Пока достаточно знать, что шаблоны помещаются в {{outlet}}

Привязка данных

Привязка данных позволяет изменениям данных модели обновляться в представлении и / или изменениям представления автоматически обновляться в модели без дополнительного кода. Односторонняя привязка данных обычно указывает, что изменения в модели распространяются на представление. Двухстороннее связывание данных добавляет возможность немедленного отображения изменений в модели. Привязка данных устраняет необходимость написания большого количества шаблонных кодов и освобождает разработчика, чтобы сосредоточиться на уникальных проблемах в приложении.

Пример AngularJS

Ниже приведен простой пример двусторонней привязки данных в AngularJS. Ввод в поле ввода покажет введенный текст после приветственного сообщения.

Пример магистрали

Backbone не имеет автоматической привязки данных, но это можно сделать вручную. На практике я обнаружил, что односторонняя привязка данных, которая обновляет представление при внесении изменений в модель, чрезвычайно полезна. Привязка данных из представления к модели реальных вариантов использования встречается реже.

Ниже приведен простой пример, где код был реализован для связывания в обоих направлениях.

Таким образом, вы прослушиваете событие изменения в модели и вызываете свойство render представления, чтобы заставить модель обновить представление. Точно так же вы слушаете keyup Этот пример должен дать вам представление о том, сколько кода требуется для работы привязки данных. Стоит также отметить, что существует множество плагинов, которые добавляют поддержку привязки данных к Backbone.

Пример Ember

Привязка данных в Ember выглядит так:

Ember использует знакомые Handlebars для создания шаблонов, но структура также включает в себя «помощники ввода» для привязки общих полей ввода формы. В фигурных скобках {{<name

Шаблоны / Просмотров

Шаблоны могут быть целыми страницами HTML, но чаще это небольшие фрагменты HTML с выражениями-заполнителями привязки данных, включенными для динамических данных. Они могут быть лишены логики, если учесть, что в ваших представлениях не должно быть практически никакой логики, в то время как другие позволяют встраивать JavaScript непосредственно в шаблон. Шаблоны могут быть на основе DOM и использовать DOM для динамической вставки динамических данных или на основе строк, обрабатывая HTML как строки и заменяя динамические части.

Давайте посмотрим на некоторые примеры.

Пример AngularJS

Вот простой пример шаблонов в AngularJS.

Вы заметите, что это очень похоже на предыдущий пример маршрутизации с добавлением привязки данных, чтобы показать, как шаблоны могут помочь в вашем приложении. Все шаблоны включены в теги scripttemplateUrl$routeProvider

Предпочтительный способ обработки шаблонов в более масштабных приложениях, где важна производительность, — это объединить и зарегистрировать ваши шаблоны AngularJS в Angular $templateCacheэта .

Пример Ember

Ниже приведен пример шаблонов в Ember.

Маршрут Ember — это объект, который сообщает шаблону, какую модель он должен отображать. Я думаю о нем как о самом простом контроллере для вашего шаблона и ресурса (URL), основной задачей которого является загрузка модели. Если вам нужно выглядеть модно и сохранять состояние приложения, вам нужен контроллер.

Пример магистрали

Теперь давайте рассмотрим простой пример шаблонов в Backbone.

Это модификация примера маршрутизации, но вместо того, чтобы жестко кодировать HTML в свойстве шаблона объекта представления, теперь разметка находится на странице HTML внутри тега scriptid Чтобы получить шаблон (фрагмент HTML), мы используем селектор jQuery, чтобы найти элемент по scriptidinnerHTML

модели

Модели являются клиентской версией того, что обычно называют бизнес-объектами, объектами домена или объектами. В общем, идея, лежащая в основе моделей в клиентских средах MV *, состоит в том, чтобы установить центральную точку для данных в приложении, а также любое поведение, которое должно быть заключено в эти данные. Эту модель можно сравнить с серверной архитектурой MVC плюс jQuery, в которой данные модели обычно хранятся в DOM. При наличии модели цель состоит в том, чтобы удалить эти данные и состояние из DOM и поместить их в общее место, где они могут быть использованы повторно.

Пример магистрали

Модели хранят данные и хранят их вне DOM, а также генерируют такие события, как change Это дает вам один источник правды, а не пользовательский интерфейс.

Я изменил пример привязки данных из предыдущего, добавив новый шаблон и представление, которое смотрит на тот же объект модели Person. Ранее я объявил модель Person на лету, чтобы все было просто, но теперь я добавил вызов Backbone.Model.extend() Обратите внимание, как оба представления прослушивают один и тот же объект модели человека (событие изменения) и обновляют себя. Имея этот единственный источник данных, многочисленные обращения к определенным элементам DOM могут быть инкапсулированы в их собственные аккуратные представления, и одна модель может обслуживать их все.

Пример AngularJS

Идея единой модели, которая является правдой о состоянии в вашем приложении, существует в AngularJS, но Angular позволяет вам использовать простые старые объекты JavaScript в качестве модели, а затем добавляет наблюдатели «под капот» к любому свойству, которое связано с данными в представлении. с директивой ng-model Затем эти наблюдатели автоматически предупреждают другие части приложения, связанные с той же моделью, и эти элементы DOM знают, как обновить себя.

Вот обновленный пример привязки данных AngularJS, показывающий две части обновляемого представления.

Доступ к данным

Доступ к данным — это способ получения и сохранения данных для вашего приложения. В общем случае фреймворки предполагают, что вы вызываете API, который возвращает вам JSON.

Пример AngularJS

AngularJS обрабатывает данные двумя различными способами. Во-первых, предоставляя поддержку для ручных вызовов Ajax очень похоже на функциональность jQuery $.ajax$http Кроме того, если ваш бэкэнд является строго RESTful-сервисом, AngularJS предоставляет класс $resource

Пример $http

 app.factory('myService', function($http) {
  return {
    getFooOldSchool: function(callback) {
      $http.get('foo.json').success(callback);
    }
  };
});

app.controller('MainCtrl', function($scope, myService) {
  myService.getFooOldSchool(function(data) {
    $scope.foo = data;
  });
});

$resource

 //create a todo
var todo1 = new Todo();
todo1.foo = 'bar';
todo1.something = 123;
todo1.$save();

//get and update a todo
var todo2 = Todo.get({id: 123});
todo2.foo += '!';
todo2.$save();

//delete a todo
Todo.$delete({id: 123});

Пример магистрали

Backbone предполагает, что вы взаимодействуете с RESTful API, но позволяет вам переопределить один метод, Backbone.sync() Вы указываете своей модели, где находится ресурс на сервере (URL), а затем можете просто вызвать save()

 var UserModel = Backbone.Model.extend({
  urlRoot: '/user',
  defaults: {
    name: '',
    email: ''
  }
});
var user = new Usermodel();
// Notice that we haven't set an `id`
var userDetails = {
  name: 'Craig',
  email: 'craigmc@funnyant.com'
};
// Because we have not set an `id` the server will call
// POST /user with a payload of {name:'Craig', email: 'craigmc@funnyant.com'}
// The server should save the data and return a response containing the new `id`
user.save(userDetails, {
  success: function (user) {
    alert(user.toJSON());
  }
});

Пример Ember

У Ember есть Ember Data, которые технически не являются частью базовой структуры, но стремятся обеспечить более надежную историю постоянного хранения / хранения данных. Он предоставляет множество возможностей, которые вы найдете в серверных ORM, таких как ActiveRecord, но разработан специально для уникальной среды JavaScript в браузере. На момент написания Ember Core Team была близка к выпуску v1.0, но этого не произошло, и многие проекты Ember просто используют методы $.ajax$http

Вывод

В этом посте были разбиты фреймворки JavaScript MV * с помощью функций, позволяющих понять, какие функциональные возможности предоставляются этими фреймворками, и донести до читателей понимание того, что они на самом деле очень похожи. Как только вы поймете особенности фреймворка и то, как они сочетаются друг с другом, становится намного проще быстро изучить несколько фреймворков и найти подходящую для вашего проекта.