Backbone.js - создание экземпляров моделей / представлений из существующих HTML - PullRequest
14 голосов
/ 21 июля 2011

Сегодня я начал рассматривать backbone.js как способ лучше организовать код в своем приложении.

Мне было интересно (концептуально - так что отвечайте псевдокодом всеми средствами), как бы я использовал свой существующий html для создания опорных моделей (и представлений).

Все найденные мной учебные пособия состоят из использования пустого 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 на странице?

Если это имеет значение, я планирую использовать усы для моих шаблонов.

Ответы [ 3 ]

15 голосов
/ 01 октября 2011

Я действительно пытался сделать то же самое, и просто нашел способ обойти это!

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

Весь код js вставляется в него как сущность https://gist.github.com/1255736с комментариями, чтобы объяснить больше.

Важная часть о том, как создать экземпляр коллекции.По сути:

  1. вы получаете ваши существующие элементы HTML через jQuery.Если представление вашей модели основано на tagName: 'li', то это тот тип тегов, который вам нужно извлечь здесь.
  2. Вы просматриваете эти теги, чтобы очистить имеющиеся там данные, составляющие ваши модели, иСоздайте свои модели
  3. Вы создаете представление для каждой модели, передавая ей модель и базовый элемент .Это была моя проблема: я создавал представление и только потом пытался добавить его позже через my_view.el = xxx.Это не работает.
  4. Вы добавляете свою модель в коллекцию

Примечание: коллекция обычно привязывается к представлению позже, так что использование 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's 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
    );
}
})

Надеюсь, это поможет!

6 голосов
/ 21 июля 2011

Представления Backbone всегда привязаны к конкретному 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 голосов
/ 16 февраля 2012

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

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

...