Backbone.js - создавать экземпляры моделей/просмотров из exhit html
Я начал искать backbone.js сегодня как способ лучше организовать код в моем приложении.
Мне было интересно (концептуально - так ответьте псевдокодом), как бы я использовал мой существующий html для создания Backbone Models (и Views).
Все учебные пособия, которые я нашел, состоят в использовании пустого шаблона html, а затем вложения в контент с помощью ajax. Я не хочу этого делать.
Если у меня есть коллекция книг.
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>My Book Collection</title>
</head>
<body>
<head>
</head>
<body>
<ul id="bookCollection">
<li class="book" data-book-id="1"><input type="text" name="book_1_name" value="My Book A"/></li>
<li class="book" data-book-id="2"><input type="text" name="book_2_name" value="My Book B"/></li>
<li class="book" data-book-id="3"><input type="text" name="book_3_name" value="My Book C"/></li>
<li class="book" data-book-id="4"><input type="text" name="book_4_name" value="My Book D"/></li>
<li class="book" data-book-id="5"><input type="text" name="book_5_name" value="My Book E"/></li>
</ul>
</body>
</body>
</html>
На этом этапе я хотел бы начать управлять каждой книгой как модель, вызывая функцию, когда имена книг изменяются (только предупреждение в функции для доказательства концепции), а затем вызов URL для синхронизации изменений с моделью с моей базой данных.
Может ли кто-нибудь указать мне в правильном направлении способ сделать это, используя существующий html на странице?
Если это имеет значение, я планирую использовать усы для моего шаблона.
Ответы
Ответ 1
Представления на основе базы данных всегда привязаны к определенному элементу html (атрибут вида el
). У вас может быть что-то вроде BookCollectionView
привязано к ul#bookCollection
и BookView
привязано к li.book
, что должно быть хорошо с вашей текущей структурой шаблона.
Вы можете сопоставить модель Book
с представлением, используя URL-адрес модели. Если модель извлекается из этого URL-адреса, и вы определили привязку события для изменения модели, соответствующее представление должно обновиться с новыми данными модели. То же самое относится к сборнику url и коллекции книг.
Не так много хороших обучающих программ на базе я думаю, но изучите что-то вроде http://liquidmedia.ca/blog/2011/02/backbone-js-part-3/ или http://www.jamesyu.org/2011/02/09/backbone.js-tutorial-with-rails-part-2/. Угадайте, что это легче, если вы можете придумать еще несколько конкретных вопросов!
Ответ 2
Я действительно пытался сделать то же самое, и просто нашел свой путь вокруг него.
Пыталась создать пример списка дел, в котором у меня уже есть какие-то todos на странице, вы хотите привести их в качестве моделей в мою коллекцию Todos и управлять ими так же, как это происходит для элементов, которые были добавлены в пустая страница.
Весь код js вставлен как сущность https://gist.github.com/1255736 с комментариями, чтобы объяснить больше.
Важная роль в том, как создать экземпляр коллекции. В основном:
- вы получаете свои существующие элементы html через jQuery. Если ваше представление модели основано на tagName: 'li', то это те теги, которые вам нужно получить здесь.
- Вы повторяете эти теги, чтобы очистить данные, которые там, которые составляют ваши модели, и создавать ваши модели.
- Вы создаете представление для каждой модели, передавая ему модель и базовый элемент. Это была проблема, с которой я столкнулся: я создавал представление и только потом пытался добавить его позже через my_view.el = xxx. Это не работает.
- Вы добавляете свою модель в коллекцию
Примечание: коллекция, как правило, привязана к представлению позже, так что, используя collection.add, также обновит представление. Поскольку инициализация вызывается в конструкторе, коллекция еще не привязана, и вы не будете дублировать элементы в своем HTML, добавив их здесь.
// this is the important part for initializing from html!
khepin.Todos = Backbone.Collection.extend({
model: khepin.Todo,
// In this function we populate the list with existing html elements
initialize: function() {
_.each(
// get all the <li></li> todo items (the base for the todo view)
// and for each of them:
$('.todo'),
function(a){
// Create the model
var todo = new khepin.Todo();
// Find the todo text
var task = $(a).find('span')[0];
task = $(task).text();
// set the model correctly
todo.set({
task: task
});
// create the todo view
var todoView = new khepin.TodoView({
model: todo,
el: a // the el has to be set here. I first tried calling new TodoView and setting the 'el' afterwards
// and the view wasn't managed properly. We set the "el' to be the <li></li> we got from jQuery
});
// Add this new model to the collection
this.add(todo);
},
this
);
}
})
Надеюсь, это поможет!
Ответ 3
У меня была та же проблема, и я решил ее таким образом в конструкторе моего основного вида (список ul) - в качестве основы 0,9.
Я преобразовал его в мой разум из синтаксиса coffeescript, поэтому, пожалуйста, будьте осторожны, если есть некоторые синтаксические ошибки.
myListView = Backbone.View.extend({
initialize: function() {
._each(this.$el.children(), function(book, i) {
new Backbone.View({
el: book,
model: this.collection.at(i)
});
});
}
});
и называя его следующим образом:
new myListView({
collection: anExistingCollection,
el: $('#bookCollection')
});
Важно, чтобы порядок коллекции 'anExistingCollection' был таким же, как и ваши уже сгенерированные записи в списках, поскольку этот пример основан на одном и том же индексе.
(непроверенные)