Настройка моей модели с помощью Backbone.js

Я пытаюсь использовать Backbone.js для упрощения управления данными (JSON) и взаимодействия с DOM.

Во-первых, я не уверен, действительно ли Backbone.js может упростить и улучшить текущий процесс, но хотелось бы предположить, что может.

Раньше я извлекал данные с помощью функции jQuery AJAX. Теперь я извлекаю данные (все еще с помощью AJAX) в стиле Backbone в модель Backbone.

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

Теперь можно ли использовать функцию set в Backbone для упрощения чего-то вроде приведенного ниже и в идеале, где должно быть построено поведение атрибута set (и все другие привязки пользовательского интерфейса, такие как события изменения)? Будет ли это в обработчике успеха fetch(), который находится в инициализаторе представления?

function setBucketOffer(bucketName, newId) {
    var segments = json.segments;
    for (var i = 0; i < segments.length; i++) {
        if (segments[i].market.toLowerCase() === g_market) {

            var genders = segments[i].gender;
            for (var i = 0; i < genders.length; i++) {
                if (genders[i].name.toLowerCase() === g_segment) {

                    var buckets = genders[i].buckets;
                    for (var i = 0; i < buckets.length; i++) {
                        if (buckets[i].name === bucketName) {

                            buckets[i].confirm = newId;
                            return;
                        }
                    }
                }
            }
        }
    }
}

Пример JSON

{
    "segments": [
        {
            "market": "Market1",
            "gender": [
                {
                    "name": "male",
                    "buckets": [
                        {
                            "name": "Market1_M_CBD",
                            "subscribers": "50,000",
                            "postcode": "20000-2010",
                            "lastsend": "13/03/12 4:30PM",
                            "suggest": "10054",
                            "confirm": ""
                        },
                        {
                            "name": "Market1_M_North",
                            "subscribers": "50,000",
                            "postcode": "20000-2010",
                            "lastsend": "13/03/12 4:30PM",
                            "suggest": "10054",
                            "confirm": ""
                        }
                    ]
                },
                {
                    "name": "female",
                    "buckets": [
                        {
                            "name": "Market1_F_CBD",
                            "subscribers": "50,000",
                            "postcode": "20000-2010",
                            "lastsend": "13/03/12 4:30PM",
                            "suggest": "10054",
                            "confirm": "10054"
                        }
                    ]
                }
            ]
        },
        {
            "market": "Market2",
            "gender": [
                {
                    "name": "male",
                    "buckets": [
                        {
                            "name": "Market2_M_CBD",
                            "subscribers": "50,000",
                            "postcode": "20000-2010",
                            "lastsend": "13/03/12 4:30PM",
                            "suggest": "10054",
                            "confirm": "10054"
                        },
                        {
                            "name": "Market2_M_North",
                            "subscribers": "50,000",
                            "postcode": "20000-2010",
                            "lastsend": "13/03/12 4:30PM",
                            "suggest": "10054",
                            "confirm": "10054"
                        },
                        {
                            "name": "Market2_M_South",
                            "subscribers": "50,000",
                            "postcode": "20000-2010",
                            "lastsend": "13/03/12 4:30PM",
                            "suggest": "10054",
                            "confirm": "10054"
                        }
                    ]
                }
            ]
        }
    ]
}

Изменить 1

Отсюда я пытаюсь эффективно использовать Parse и получать только сегменты из своего JSON:

var Offers = Backbone.Collection.extend({
    url: 'URL',
    parse: function (response) {
        return response.segments;
    }
});

Здесь я получаю больше, чем просто response.segments. Также не уверен, правильно ли мне использовать функцию рендеринга или функцию получения успеха для заполнения DOM. Предположим, у меня есть мой html-шаблон в DOM... Я хочу клонировать его с помощью jQuery clone() и заполнять клон с помощью forEach для сегментов и возвращать все клоны в тело html. Работает ли это в магистрали, как бы вы это сделали? (Я могу сделать это без backbone.js, но хотел бы посмотреть, как я могу улучшить с помощью backbone.js и привязать все данные о клонах к изменениям модели)

var OfferView = Backbone.View.extend({
    initialize: function () {
        this.model = new Offers();
        this.model.fetch({
            success: function (collection, response) {
                console.log(response);
            }
        });
        this.model.on('change', this.modelChange);
        this.model.on('change', this.render);
        this.modelChange = function () {
            alert('model changed');
        };
    },
    render: function () {

    }
});

Изменить 2

Я собираюсь создавать отдельные представления через forEach, но у меня возникают проблемы с их вставкой обратно в DOM. Что я делаю неправильно? (Не уверен в возврате этой части)

// DEFINE VIEW
var OfferView = Backbone.View.extend({
    initialize: function () {
        this.model = new Offers();
        this.model.fetch();
        this.model.on('change', this.modelChange);
        this.model.on('change', this.render);
        this.modelChange = function () {
            alert('model changed');
        };
        this.render();
    },
    render: function () {
        var self = this;
        this.model.forEach(function (s) {
            var view = new OfferMarketView({
                id: "container" + s.get('name').toLowerCase().replace(/\s*/g, '')
            });
            $('#leftCol').append(view.el);
        });
        return this;
    }
});
var OfferMarketView = Backbone.View.extend({
    tagName: "div",
    className: "marketContainer",
    events: {},
    render: function() {
    }
});

person bcm    schedule 21.03.2012    source источник
comment
как выглядит ваш ответ JSON и как выглядит ваша модель? Трудно помочь, не видя их.   -  person tkone    schedule 21.03.2012
comment
Мне не нужна точная рабочая альтернатива. Хотелось бы, чтобы последний абзац вопроса был рассмотрен для любой базовой модели json › с множественной вложенностью.   -  person bcm    schedule 21.03.2012
comment
Трудно сказать, не глядя на образец вашего JSON. Я имею в виду, да, вы можете это сделать. Как? Это отличный вопрос. Возможно, вам придется сначала преобразовать свой JSON. Возможно, вам придется использовать магистральный плагин. Возможно, вы сможете сделать это напрямую. Однако, не видя больше кода, трудно дать вам лучший ответ.   -  person tkone    schedule 21.03.2012
comment
Здесь опубликован новый вопрос о возвращении дочерних представлений в DOM. stackoverflow .com/questions/9799623/   -  person bcm    schedule 21.03.2012


Ответы (1)


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

parse: function(response) {

}

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

Для привязки событий вы захотите сделать это в своем представлении. В методе инициализации вашего представления вы можете сделать что-то вроде:

this.collection.on("change", this.someFunction);

Теперь каждый раз, когда что-то заставляет эту модель инициировать событие изменения someFunction (также определенное в вашем представлении), будет запущено.

ИЗМЕНИТЬ

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

в вашем файле коллекции, если вы создаете метод синтаксического анализа, который делает следующее:

parse: function(response) {
    return response.segments;
}

Когда вы вызываете свою выборку, this.collection.fetch() при успешном запросе, ваша коллекция будет заполнена моделями, которые содержат атрибуты в структуре, соответствующей вашему ответу.

ИЗМЕНИТЬ 2

Ваша привязка выглядит нормально.

в этом разделе кода:

this.collection.fetch({
    success: function (model, attributes) {
        initAll(attributes);

        // populate ui with attributes from model
    }
})

Параметры, которые передаются обратно при успешном извлечении коллекции, таковы: (collection, response) collection является результатом вызова коллекции и тем, что в конечном итоге будет this.collection. response — это ответ на ваш запрос ajax.

Я не уверен, что initAll(attributes) должен делать. Если вы добавите метод синтаксического анализа, как я написал выше, ваша коллекция будет содержать набор моделей с атрибутами каждого сегмента.

Кроме того, вместо вызова this.render() в конце вы можете выполнить привязку рендеринга к событию изменения:

this.collection.on('change', this.render);

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

person ryanmarc    schedule 21.03.2012
comment
Привет, Райан, спасибо за совет по разбору. Могу предположить, что это будет полезно. Что касается изменения модели, можете ли вы посмотреть, является ли код, который я добавил, правильным/идеальным? - person bcm; 21.03.2012
comment
Когда я консольно регистрирую коллекцию, я получаю весь магистральный объект. Также, когда я консольно записываю ответ, я получаю полный ответ JSON. Разбор, кажется, не имеет никакого эффекта ... Это правильно? // ОПРЕДЕЛЕНИЕ МОДЕЛИ Offer = Backbone.Model.extend(); var Offers = Backbone.Collection.extend({ model: Offer, url: 'URL', parse: function (response) { return response.segments } }); - person bcm; 21.03.2012
comment
Вам не нужно определять модель, если у вас нет модели, которую вы расширили и вам нужно ее использовать. Backbone создаст модели и поместит их в вашу коллекцию. Когда вы консольно регистрируете коллекцию, вы должны увидеть атрибут с именем models, каждый из них должен иметь атрибут с именем attribute, и там будут данные для каждого элемента. Response показывает нетронутый ответ сервера, так что да, это правильно, вы должны увидеть там все. - person ryanmarc; 21.03.2012
comment
Привет, Райан, спасибо за объяснение. Я удалил модель и просто использовал коллекцию с разбором внутри. Я все еще довольно заблокирован и надеюсь, что мое редактирование 1 выше объяснит лучше, чего я надеюсь достичь. - person bcm; 21.03.2012
comment
когда вы регистрируете свою коллекцию внутри успеха, console.log(collection) что в ней? Это должен быть объект базовой коллекции с узлом с именем models. Это должен быть массив базовых моделей, и каждая из них должна иметь узел с именем атрибутов. Внутри вы должны увидеть детали для ответа на синтаксический анализ. Не клонируйте свой дом и не добавляйте его с помощью forEach. используйте this.collection.each(function(model) { }); и внутри создайте новый вид из каждой модели и добавьте его в дом. Это был бы основной путь, который вы ищете. - person ryanmarc; 21.03.2012
comment
Вы не должны пытаться использовать реакцию, которая возвращается к вашему успеху. В этот момент он доступен для справки, если вам это нужно, но при условии, что все прошло правильно, вы должны использовать возвращенную коллекцию с этого момента во всем своем приложении. - person ryanmarc; 21.03.2012
comment
Попытка переварить... То, что вы объясняете, похоже, здесь - stackoverflow.com/questions/7400532/ (сейчас попробую) - person bcm; 21.03.2012
comment
Да, это то, что я имею в виду. На данный момент я более чем ответил на исходный вопрос здесь. Если это было полезно, я бы предложил принять ответ, а затем начать новый вопрос, если вы конкретно относитесь к этой проблеме. Я бы также рекомендовал просмотреть документацию по магистральной сети и прочитать ее. Это довольно коротко и объясняет все, что вам действительно нужно для начала. - person ryanmarc; 21.03.2012
comment
Я думаю, что почти у цели (Редактировать 2), у меня возникли проблемы с возвратом вновь созданных представлений в DOM. - person bcm; 21.03.2012