如何更新模型是集合的一部分

时间:2014-02-07 13:56:07

标签: javascript backbone.js requirejs

我的应用程序使用backbone.js和requirejs,我有一个“问题模块,显示数据库及其答案的问题”,下面是模块的结构:

  1. 观点/问题观点
  2. 观点/问题项目视图
  3. 收集/问题收集
  4. 模特/问题模型
  5. 我的应用程序一切正常,因为我可以从集合中检索所有数据并将其呈现到页面。本周早些时候,在创建包含向上和向下按钮的评级系统时,我遇到了一个问题,

    我需要做的是在用户点击带有新值的向上/向下按钮时更新模型,然后使用新值重新渲染项目视图。

    我将附上上面提到的四个页面的代码,下面代码中的所有内容都完美地运行,并且我没有包含任何应该处理更新过程的函数或事件。

    问题视图

    // Filename: views/_activity_slider_inHeader
    define([
    'jquery',
    'underscore',
    'backbone',
    'app/config',
    'app/collections/questions',
    'app/views/home_question_item',
    'text!templates/questions_home.html',
    'bootbox'
    ], function($, _, Backbone, Config, QuestionsCollection, SingleQuestionView, question_slider_template, bootbox) {
    var ActivitySlider = Backbone.View.extend({
        el: $(".content_container"),
        template: _.template(question_slider_template),
        initialize: function() {
            /*
             * initial script
             */
            var questionsCollection = new QuestionsCollection();
            this.collection = questionsCollection;
            questionsCollection.fetch({
                reset: true,
                error: function(model, xhr, options) {
                    /*
                     * When triggering error:
                     *      1. If ther response is not valid json
                     *      2. There is error connecting to the server
                     */
                    if (xhr['readyState'] === 1 | xhr['status'] === 404) {
    
                        /*
                         * the connection has not been made, user may be not connected to the internet
                         * @readyState The state of the request:
                         *             0 = UNSENT
                         *             1 = OPENED
                         *             2 = HEADERS_RECEIVED
                         *             3 = LOADING
                         *             4 = DONE
                         */
                        var msg = "pla pla",
                                title = "pla pla";
    
                        bootbox.dialog({
                            /*
                             * bootbox.dialog, bootbox.prompt, bootbox.confirm, bootbox.alert
                             * bootbox should have a callback used for the buttons
                             */
                            message: msg,
                            title: title,
                            buttons: {
                                main: {
                                    label: "pla pla",
                                    className: "",
                                    callback: function() {
    
                                    }
                                }
                            }
                        });
    
                    }
                    if (xhr['readyState'] === 4 & xhr['status'] === 200) {
                        /*
                         * Handling empty data
                         * connections to the server made successfully but seems to be there is no data returned by the server
                         */
    
                    }
                }
            });
            this.listenTo(this.collection, 'reset', this.render);
            this.renderList();
        },
        render: function(questions) {
    
            /*
             * Ilterate through all activities and start rendering item by item through the SingleActivityView
             */
            if (questions.size() === 0) {
                /*
                 * there is no available activities
                 * further use ..
                 */
    
            } else {
    
                var i = 1;
                //there is activities available
                questions.each(function(question) {
                    //create instance of the single item view
                    var current = question.attributes,
                            singleQuestionView = new SingleQuestionView({
                        model: question,
                        collection: this.collection,
                        id: i
                    });
                    this.$el.append(singleQuestionView.render().el);
    
                    i++;
                }, this);
    
            }
    
        },
        renderList: function() {
            /*
             * rendering the slider structure itself first
             */
            var data = {
                path: Config.baseUrl,
                _: _
            };
            this.$el.append(this.template(data));
        }
    });
    
    return ActivitySlider;
    
    });
    

    问题项目视图

    /* Filename: views/home_question_item
    * used to handle one row of the questions objects, merge the model data onto call list item
    */
    define([
    'jquery',
    'underscore',
    'backbone',
    'app/config',
    'text!templates/question_item_home.html',
    'string',
    'moment',
    'moment_ar',
    'jquerycookie',
    'purl'
    ], function($, _, Backbone, Config, QuestionItemTemplate, S, moment, moment_ar) {
    var url = $.url(),
        ActivityItemView = Backbone.View.extend({
        el: $("li"),
        template: _.template(QuestionItemTemplate),
        initialize: function(){
    
        },
        render: function() {
    
            var model = this.model.attributes;
    
            var data = {
                path: Config.baseUrl,
                lang: url.segment(1),
                id: model['id'],
                date: model['date'],
                views: model['views'],
                author: model['author'],
                authorName: model['authorName'],
                question: model['question'],
                answer: model['answer'],
                rate: model['rate'],
                _ : _,
                S: S,
                moment: moment
            };
    
            $(".list_of_question").append(this.template(data));
            return this;
        },
        close: function(){
            console.log('destroyed');
            $(this.el).unbind();
            $(this.el).remove();            
        }
    });
    return ActivityItemView;
    });
    

    问题集

    // Filename: collections/activities
    define([
    'jquery',
    'underscore',
    'backbone',
    'app/config',
    'app/models/question',    
    'moment',
    'purl'
    ], function ($, _, Backbone, Config, question, moment) {
    
    var url = $.url(),
        ActivitiesCollection = Backbone.Collection.extend({
    
        model: question,
        url: Config.baseUrl + url.segment(1) + '/pull/questions'
    
    });
    return ActivitiesCollection;
    });
    

    问题模型

    // Filename: models/activity
    define([
    'jquery',
    'underscore',
    'backbone',
    'app/config',
    'purl'
    ], function ($, _, Backbone, Config) {
    
    var url = $.url(),
        ActivityModel = Backbone.Model.extend({
        defaults: {
            id: 'N/A'
        },
        urlRoot: Config.baseUrl + url.segment(1) + '/pull/questions/'
    
    });
    return ActivityModel;
    
    });
    

1 个答案:

答案 0 :(得分:0)

我没有测试过代码,但它应该是这样的:

var ActivityItemView = Backbone.View.extend({
    el: $("li"),
    template: _.template(QuestionItemTemplate),
    initialize: function(options){
        this.model = options.model;
        this.listenTo(this.model, 'change', this.render, this); 
    },
    events : {
        'click #arrowUp' : 'increaseModelRating',
        'click #arrowDown' : 'decreaseModelRating',
    },
    render: function() {
        var data = { '...' };
        $(".list_of_question").append(this.template(data));
        return this;
    },
    increaseModelRating: function() {
        var currentRating = this.model.get('rating');
        this.model.set('rating', ++currentRating);
    },
    decreaseModelRating: function() {
        var currentRating = this.model.get('rating');
        this.model.set('rating', --currentRating);
    },  
    close: function() { '...' }
});