Статьи

Погружение в CanJS: часть 3

Это заключительная часть учебника из трех частей , который научит вас создавать приложение диспетчера контактов в JavaScript с использованием CanJS и jQuery. Когда вы закончите с этим руководством, у вас будет все, что вам нужно, чтобы создавать свои собственные приложения JavaScript с использованием CanJS!

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

В этой части урока вы будете:

  • Редактировать и удалять контакты с помощью управления Contact
  • Создать элемент управления и просмотра для создания контактов
  • Прослушивание событий DOM и Model с использованием шаблонных обработчиков событий Control

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


В первой части contactView.ejs поместил каждое свойство контакта во входной тег. Чтобы обновить контакт при изменении этих входов, вам нужно добавить некоторые обработчики событий в Contact управления Contact . Добавьте этот код contacts.js в Contacts управления Contacts :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
‘.contact input focusout’: function(el, ev) {
  this.updateContact(el);
},
‘.contact input keyup’: function(el, ev) {
  if(ev.keyCode == 13){
    el.trigger(‘blur’)
  }
},
‘.contact select change’: function(el, ev) {
  this.updateContact(el)
},
updateContact: function(el){
  var contact = el.closest(‘.contact’).data(‘contact’);
  contact.attr(el.attr(‘name’), el.val()).save();
}

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

1
2
3
‘.contact input focusout’: function(el, ev) {
  this.updateContact(el);
},

Вызывает updateContact() когда любой <input> теряет фокус.

1
2
3
4
5
‘.contact input keyup’: function(el, ev) {
  if(ev.keyCode == 13){
    el.trigger(‘blur’)
  }
}

Запускает событие blur на <input> если клавиша ввода нажата, когда он находится в фокусе. Это приведет к тому, что ввод потеряет фокус, который обрабатывается обработчиком события focusout .

1
2
3
‘.contact select change’: function(el, ev) {
  this.updateContact(el)
},

Вызывает updateContact() когда значение <select> изменяется.

1
var contact = el.closest(‘.contact’).data(‘contact’);

Находит ближайший родительский тег <li> и извлекает экземпляр модели, используя $.data() .

1
contact.attr(el.attr(‘name’), el.val()).save();

Обновляет контакт, используя attr() . Имя каждого <input> соответствует свойству контакта, поэтому el.attr('name') вернет имя обновляемого свойства. save() используется для сохранения изменения в модели Contact .


В верхнем правом углу каждого контакта есть небольшая ссылка со знаком «X». При нажатии на этот контакт контакт должен быть удален. Для этого добавьте еще один обработчик событий в элемент управления « Contacts который выглядит следующим образом:

1
2
3
‘.remove click’: function(el, ev){
  el.closest(‘.contact’).data(‘contact’).destroy();
}

При нажатии на X экземпляр контакта извлекается из ближайшего <li> и вызывается destroy() . destroy() удаляет контакт из Модели и удаляет его из любых Model.Lists.

Прямая привязка автоматически обновит ваш пользовательский интерфейс при удалении контакта.

Теперь вы создадите Control и View, необходимые для создания контакта. Сначала вам понадобится гигантская кнопка «Новый контакт». Добавьте этот код в index.html прямо над <div id="filter"> :

1
2
3
<a class=»btn btn-large btn-primary» href=»javascript://» id=»new-contact»>
  <i class=»icon-plus icon-white»></i> New Contact
</a>

Вам также необходимо создать новый вид, который будет отображать форму для создания контакта. Сохраните этот код как createView.ejs в папке представлений:

01
02
03
04
05
06
07
08
09
10
11
<div class=»hero-unit contact span8″>
  <%== can.view.render(‘views/contactView.ejs’, {
    contact: contact, categories: categories
  }) %>
  <div class=»row»>
    <div class=»buttons pull-right»>
      <a href=»javascript://» class=»btn btn-primary save»>Save</a>
      <a href=»javascript://» class=»btn cancel»>Cancel</a>
    </div>
  </div>
</div>

Это представление отображает под-шаблон contactView.ejs и добавляет кнопки «Сохранить» и «Отмена». Вот как это выглядит в приложении:

Создать вид

Теперь вам нужно создать новый элемент управления с именем Create который будет отображать форму и сохранять новый контакт в модель Contact . Добавьте этот код в contacts.js :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Create = can.Control({
  show: function(){
    this.contact = new Contact();
    this.element.html(can.view(‘views/createView.ejs’, {
      contact: this.contact,
      categories: this.options.categories
    }));
    this.element.slideDown(200);
  },
  hide: function(){
    this.element.slideUp(200);
  },
  ‘.contact input keyup’: function(el, ev) {
    if(ev.keyCode == 13){
      this.createContact(el);
    }
  },
  ‘.save click’ : function(el){
    this.createContact(el)
  },
  ‘.cancel click’ : function(){
    this.hide();
  },
  createContact: function() {
    var form = this.element.find(‘form’);
      values = can.deparam(form.serialize());
 
    if(values.name !== «») {
      this.contact.attr(values).save();
      this.hide();
    }
  }
});

Давайте подробно рассмотрим этот элемент управления, чтобы увидеть, что происходит:

1
2
3
4
5
6
7
8
show: function(){
  this.contact = new Contact();
  this.element.html(can.view(‘views/createView.ejs’, {
    contact: this.contact,
    categories: this.options.categories
  }));
  this.element.slideDown(200);
},

Создает пустой контакт, используя new Contact({}) и назначает его этому this.contact . Новый контакт передается в can.view() вместе с отображаемыми категориями.

1
2
3
hide: function(){
  this.element.slideUp(200);
},

Выдвигает форму из поля зрения.

1
2
3
4
5
‘.contact input keyup’: function(el, ev) {
  if(ev.keyCode == 13){
    this.createContact(el);
  }
}

Вызывает createContact() если клавиша ввода нажата во время одного из входов.

1
2
3
‘.save click’ : function(el){
  this.createContact(el)
},

Вызовите createContact() когда нажата кнопка «Сохранить».

1
2
3
‘.cancel click’ : function(){
  this.hide();
},

Вызывает hide() при нажатии кнопки «Отмена».

1
2
var form = this.element.find(‘form’);
  values = can.deparam(form.serialize());

Находит элемент <form> и использует функцию serialize() jQuery, чтобы получить строку, представляющую все значения формы. Затем сериализованная строка преобразуется в объект с помощью can.deparam() .

1
2
3
4
if(values.name !== «») {
  this.contact.attr(values).save();
  this.hide();
}

Если имя контакта не пустое, attr() используется для обновления контакта, сохраненного в this.contact . save() вызывается для сохранения изменений в модели, а форма скрывается путем вызова hide() .


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

Вы настраиваете поведение обработчика, используя {NAME} в обработчике событий. Переменная внутри фигурных скобок сначала просматривается в this.options , а затем в window . Вы можете создать несколько экземпляров одного и того же элемента управления, но настроить поведение его обработчиков событий в каждом экземпляре.

Элементы управления также могут связываться с объектами, отличными от this.element используя шаблонные обработчики событий. Если переменная внутри {NAME} является объектом, Control будет связываться с этим объектом для прослушивания событий. Объект не обязательно должен быть элементом DOM, это может быть любой объект, например Model. Чтобы прослушать клик в любом месте страницы, которую вы используете: '{document} click' . как ваш обработчик событий.

Эти обработчики будут очищены после уничтожения экземпляра Control. Это очень важно для предотвращения утечек памяти, которые часто встречаются в приложениях JavaScript.

Вам нужно будет использовать шаблонный обработчик событий, чтобы показать форму при нажатии кнопки «Новый контакт». Добавьте этот обработчик событий в Create управления Create в contacts.js :

1
2
3
‘{document} #new-contact click’: function(){
  this.show();
}

Кнопка «Новый контакт» находится за пределами элемента « Create элемент управления», поэтому в качестве селектора кнопки используется '{document} #new-contact' . Когда она нажата, форма откроется.


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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
$(document).ready(function(){
  $.when(Category.findAll(), Contact.findAll()).then(function(categoryResponse, contactResponse){
    var categories = categoryResponse[0],
      contacts = contactResponse[0];
 
    new Create(‘#create’, {
      categories: categories
    });
    new Contacts(‘#contacts’, {
      contacts: contacts,
      categories: categories
    });
    new Filter(‘#filter’, {
      contacts: contacts,
      categories: categories
    });
  });
})

С этим изменением в элементе #create будет создан #create элемента управления #create . Будет пройден список категорий.


Когда создается новый контакт, необходимо Model.List хранящийся в Model.List управления Contacts . Вы делаете это с помощью шаблонных обработчиков событий. Добавьте этот обработчик событий в Contacts управления Contacts в contacts.js :

1
2
3
‘{Contact} created’ : function(list, ev, contact){
  this.options.contacts.push(contact);
}

Это привязывается к created событию модели Contact . Новый контакт добавляется в Model.List хранящийся в Model.List управления Contacts с помощью push() .

Прямая привязка автоматически обновит пользовательский интерфейс ваших приложений, когда контакт будет добавлен в this.options.contacts .

Это все для заключительной части этого урока. В третьей части вы:

  • Используемые обработчики событий в элементе управления для создания нового контакта
  • Создан вид, который отображает форму создания
  • Использовали шаблонные обработчики событий в элементе управления для привязки к объектам, отличным от элемента элемента управления

Это конец учебника менеджера контактов CanJS. Вот краткое изложение того, что было рассмотрено в этом уроке из трех частей:

  • Создание элементов управления для управления логикой приложения
  • Рендеринг частей приложения с помощью Views
  • Представление уровня данных приложения с использованием моделей
  • Имитация службы REST с помощью приборов
  • Использование динамической привязки для синхронизации пользовательского интерфейса приложения с уровнем данных
  • Прослушивание событий с помощью обработчиков событий Control
  • Работа со списками экземпляров модели с использованием Model.List

Теперь у вас есть все необходимое для создания приложений JavaScript с использованием CanJS. Иди, сделай что-нибудь классное

Для полной документации и других примеров приложений посетите CanJS . Спасибо за прочтение!