Статьи

Руководство для начинающих по KnockoutJS: часть 1

Руководство для начинающих по KnockoutJS: основы и наблюдаемые

Почти каждый, кто занимается веб-технологиями, знает jQuery или, по крайней мере, слышал об этом. Его непревзойденная простота и лаконичность значительно облегчают жизнь миллионам веб-разработчиков по всему миру — и это фантастика.

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

И вот тут-то и появляется Knockout . Knockout — это библиотека JavaScript, которая помогает создавать многофункциональные веб-интерфейсы, похожие на настольные. Это упрощает взаимодействие с пользователем и делает интерфейсы полностью реагирующими на любые изменения источника данных. Knockout предоставляет простой механизм двустороннего связывания для связи модели данных с пользовательским интерфейсом, что делает синхронизацию между ними проще простого.

Хотя вам нужно будет использовать Knockout с jQuery одновременно, в некоторых случаях, например, с анимированными переходами, сам Knockout не зависит от него. Еще одна вещь, которую вам нужно понять, это то, что Knockout не конкурирует с jQuery — они оба отлично работают; каждый в своем направлении. Как вы увидите, если вы хотите получить максимальную выгоду, вы должны использовать их вместе.

В этом уроке мы начнем с основных понятий и возможностей Knockout. Во второй части мы углубимся в изучение встроенных привязок и способов их использования. И в финале мы рассмотрим некоторые расширенные функции и методы, такие как расширенные наблюдаемые и способы создания собственных пользовательских привязок. Давайте начнем!

Основные понятия

Прежде чем мы рассмотрим примеры кода, сначала вам может понадобиться понять некоторые основные понятия. Knockout реализует шаблон проектирования Model-View-View Model (MVVM) для JavaScript. В этом шаблоне ваше приложение разделено на три части:

Модель, которая содержит данные вашего приложения. Это могут быть данные, введенные пользователями, или данные JSON, полученные с веб-сервера.

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

Представление, которое относится ко всем элементам пользовательского интерфейса в вашем приложении. Это представление структуры и внешнего вида для данного пользовательского интерфейса. Представление отвечает за отображение данных и принятие ввода пользователя. Вид представлен HTML / CSS кодом в вашем приложении.

Это три основные концепции, на которых построен Knockout:

1. Декларативные привязки: они позволяют вам соединять части вашего интерфейса с вашей моделью данных простым и удобным способом. При непосредственном использовании JavaScript для манипулирования DOM это может привести к повреждению кода, если впоследствии вы измените иерархию DOM или идентификаторы элементов. С декларативными привязками, даже если вы меняете DOM, все связанные части остаются связанными. Вы можете привязать данные к DOM, просто включив атрибут привязки данных к любому элементу DOM.

2. Отслеживание зависимостей. К счастью, привязки и особый тип переменных, называемых наблюдаемыми, каждый раз, когда данные модели изменяют все части, связанные с ними, автоматически обновляются. Не нужно беспокоиться о добавлении обработчиков событий и слушателей. Вся эта дополнительная работа выполняется внутри Knockout и observables, которые уведомляют слушателей об изменении базовых значений.

3. Шаблонирование: это удобно, когда ваше приложение становится более сложным, и вам нужен способ отобразить богатую структуру данных модели представления, таким образом сохраняя ваш код простым. Knockout имеет встроенный встроенный шаблонизатор, который вы можете использовать прямо сейчас. Но если вы хотите, сторонний шаблонизатор, такой как jquery.tmpl или Underscore, также может быть использован.

Не волнуйтесь, если эта теория кажется вам неясной. Когда мы пройдем учебник и примеры кода, все станет понятнее.

Начиная

Перед тем, как мы углубимся в Knockout, вам необходимо скачать и сослаться на библиотеку в вашем HTML-документе.

<script type='text/javascript' src='knockout-2.0.0.js'></script> 

Чтобы сохранить код отдельно от презентации, лучше создать файл JavaScript для хранения всего кода приложения. И поскольку в некоторых случаях мы будем использовать jQuery, вам тоже нужно сослаться на него.

 <script type='text/javascript' src='jquery-1.7.1.min.js'></script> <script type='text/javascript' src='knockout-2.0.0.js'></script> <script type='text/javascript' src='application.js'></script> 

Это считается наилучшей практикой, но для целей обучения и упрощения вы можете поместить код JavaScript в тот же документ, включив его в тег head или поместив его под разметкой.

Теперь, чтобы создать модель представления, просто объявите любой объект JavaScript следующим образом:

  function viewModel() { // Your code here }; 

Атрибут привязки данных (объясненный позже) не является родным для HTML, и браузер не знает, что он означает. Таким образом, чтобы эффект вступил в силу, нужно активировать Knockout, вставив ko.applyBindings() в конец скрипта. Также, если вы используете внешний файл JavaScript или ваш скрипт помещен в тег head вашего документа, вам нужно обернуть код Knockout в функцию jQuery ready, чтобы он работал правильно. Вот основной шаблон для начала:

 $(document).ready(function(){ function viewModel() { // Your code here }; ko.applyBindings(new viewModel()); }); 

Вызов ko.applyBindings() и передача в нашу модель представления указывает Knockout связать указанную модель с нашим пользовательским интерфейсом. Вы даже можете предоставить элемент DOM, если хотите связать эту модель представления только с одной частью вашего общего пользовательского интерфейса. ko.applyBindings() принимает два параметра. Первый параметр говорит, какой объект модели представления вы хотите использовать с декларативными привязками, которые он активирует. Второй параметр является необязательным и определяет, в какой части документа вы хотите искать атрибуты привязки данных. Например, ko.applyBindings(viewModel, document.getElementById('container')) ограничит активацию элементом с идентификатором контейнера и его потомками. Это полезно, если вы хотите иметь несколько моделей представлений и связывать каждую из них с отдельным регионом страницы.

Как это устроено

С помощью Knockout вы можете привязать данные к элементу DOM, включив в разметку атрибут привязки данных, который задает привязку данных для выполнения. Код никогда не ссылается на структуру DOM, поэтому вы можете свободно изменять HTML, не нарушая привязки. В следующем примере мы добавляем текстовый атрибут data-bind к элементу span следующим образом:

 // syntax: data-bind="bindingName: bindingValue" <p>The day of the week is <span data-bind="text: dayOfWeek"></span>. It's time for <span data-bind="text: activity"></span></p> 

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

  function viewModel () {
   this.dayOfWeek = ko.observable ('Sunday');
   this.activity = ko.observable ('rest');
 };

 ko.applyBindings (new viewModel ()); 

Будет выведено «День недели — воскресенье. Время отдыхать».

Наблюдаемые

Knockout реализует наблюдаемые свойства, оборачивая свойства объекта пользовательской функцией с именем ko.observable() .

  this.property = ko.observable ('value') 

Наблюдаемые задаются как функции. Таким образом, вы можете использовать их следующим образом:

 // To read the observable's current value, just call the observable with no parameters. // The following will return Sunday this.dayOfWeek() // To write a new value to the observable, call the observable and pass the new value as a parameter. // The following will change the day of week to Monday this.dayOfWeek('Monday') // To write values to multiple observable properties on a model object, you can use chaining syntax. this.dayOfWeek('Monday').activity('work') 

Нокаут не требует использования наблюдаемых свойств. Если вы хотите, чтобы элементы DOM получали значения один раз, но не обновлялись при изменении значений в исходном объекте, простых объектов будет достаточно. Однако, если вы хотите, чтобы ваш исходный объект и целевые элементы DOM оставались синхронизированными — двухстороннее связывание — тогда вам следует рассмотреть возможность использования наблюдаемых свойств.

В некоторых случаях вам может потребоваться объединить значения двух или более наблюдаемых в одно новое значение. Это можно сделать с помощью так называемых вычисляемых наблюдаемых. Вычисляемые наблюдаемые — это функции, которые зависят от одной или нескольких других наблюдаемых и будут автоматически обновляться при изменении любой из этих зависимостей. Вычисляемое свойство автоматически обновляется, когда изменяется любая из наблюдаемых, от которых оно зависит. В следующем примере вычисляемая наблюдаемая с именем fullDate будет обновляться каждый раз, когда fullDate одна или несколько наблюдаемых day , month и year .

 <p>Day: <input data-bind="value: day" /></p>  <p>Month: <input data-bind="value: month" /></p>  <p>Year: <input data-bind="value: year" /></p> <p>The current date is <span data-bind="text: fullDate"></span></p>   function viewModel() { this.day = ko.observable('24'); this.month = ko.observable('02'); this.year = ko.observable('2012'); this.fullDate = ko.computed(function() { return this.day() + "/" + this.month() + "/" + this.year(); },this); }; ko.applyBindings(new viewModel()); 

ko.computed() принимает второй параметр this . Без передачи этого было бы невозможно сослаться на this.day() , this.month() или this.year() . Чтобы упростить вещи, вы можете создать переменную self , таким образом избегая добавления второго параметра. Отныне мы будем использовать этот подход в примерах кода.

 function viewModel() { var self = this; self.day = ko.observable('24'); self.month = ko.observable('02'); self.year = ko.observable('2012'); self.fullDate = ko.computed(function() { return self.day() + "/" + self.month() + "/" + self.year(); }); }; ko.applyBindings(new viewModel()); 

Когда вы имеете дело с одним объектом, вы можете легко отследить любые изменения в нем, превратив его в наблюдаемый. Но что, если у вас есть несколько объектов? В таких случаях Knockout имеет специальный объект, называемый ko.observableArray() , который может обнаруживать и реагировать на изменения коллекции вещей. Это позволяет отображать и / или редактировать несколько значений, например, когда вам нужно, чтобы повторяющиеся разделы пользовательского интерфейса появлялись и исчезали при добавлении и удалении элементов.

Следует помнить, что наблюдаемый массив отслеживает, какие объекты находятся в массиве, а не состояние этих объектов. Простое помещение объекта в наблюдаемый массив не делает все свойства этого объекта видимыми. Если вы хотите, вы можете сделать эти свойства наблюдаемыми, но это полностью ваше дело. Наблюдаемый массив просто отслеживает, какие объекты он содержит, и уведомляет слушателей, когда объекты добавляются или удаляются.

 this.property = ko.observableArray(); 

Когда вы создаете наблюдаемый массив, вы можете оставить его пустым или заполнить его некоторыми начальными значениями. В следующем примере мы создаем наблюдаемый массив, заполненный днями недели:

 <p>Today is <span data-bind="text: daysOfWeek()[0]"></span></p>  function viewModel() { var self = this; self.daysOfWeek = ko.observableArray([ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' ]); alert("The week has " + self.daysOfWeek().length + " days"); }; ko.applyBindings(new viewModel()); 

Как видите, для чтения и записи массива Knockout вы можете использовать любые встроенные функции JavaScript. Но у Knockout есть свои эквивалентные функции, синтаксис которых немного удобнее:

 array().push('Some value'); // native JavaScript array.push('Some value'); // Knockout 

Полный список доступных функций вы можете посмотреть в документации .

Если вам понравилось читать этот пост, вы полюбите Learnable ; место, чтобы узнать новые навыки и приемы у мастеров. Участники получают мгновенный доступ ко всем электронным книгам и интерактивным онлайн-курсам SitePoint, таким как JavaScript Programming for the Web .