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

标签 javascript backbone.js requirejs

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

  1. 观点/问题 View
  2. 查看/问题项查看
  3. 收藏/问题收藏
  4. 模型/问题模型

我的应用程序一切正常,因为我可以从集合中检索所有数据并将其呈现到页面。本周早些时候,我在创建由向上和向下按钮组成的评级系统时遇到了一个问题,

我需要做的是,当用户使用新值单击向上/向下按钮时更新模型,并使用新值再次重新渲染项目 View 。

我将为您附上上述四个页面的代码,下面代码中的所有内容都运行良好,并且我没有包含任何应处理更新过程的函数或事件。

问题 View

// 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;

});

问题项目 View

/* 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;

});

最佳答案

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

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() { '...' }
});

关于javascript - 如何更新模型是集合的一部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21629620/

相关文章:

javascript - 有没有办法将事件绑定(bind)到具有 Backbone 和/或 Backbone-Relational 的所有嵌套模型?

javascript - 如何查看 Chrome DevTools 中元素触发的事件?

javascript - 减少 amcharts 序列条形图中条形之间的间隙

javascript - 当 Backbone View 仍在组装 DOM 元素时,如何在 DOM 元素上设置事件触发器?

javascript - 使用 Webpack 需要第三方 RequireJS 模块

javascript - 使用 Require.js 使 Backbone.js 模块化

javascript - 在Ember CLI构建的Ember JS中,如何调用不同 Controller 上的方法?

javascript - d3 在给定半径内为气泡图设置动画

javascript - 显示在 animateCongrat() 函数中花费的时间

javascript - 如何在渲染模板后触发功能