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' был таким же, как и ваши уже сгенерированные записи в списках, поскольку этот пример основан на одном и том же индексе.

(непроверенные)