如何更新 Backbone JS 模型属性?

How to update Backbone JS model attribute?

更新:我更新了我的观点,以展示我如何使用已接受答案中的信息解决此问题。

我想 update/increment 我的 Backbone JS 模型的一个属性 ('video_views') 通过我视图中的点击事件。但是,作为一个 Backbone 菜鸟,我不确定如何准确地做到这一点。

我希望 'video_views' 属性随着 playVideo 事件(点击)递增 1。

感谢您的帮助!

这是我的 JSON 来自 API 的结构:

{
"id": 8,
"name": "Bike to work day",
"slug": "bike-work-day",
"tagline": "A brief tagline about the video.",
"description": "This is a test.",
"created": "2015-02-06T15:22:26.342658Z",
"website": "http://thevariable.com/",
"logo": "http://dev.thevariable.com/media/brands/logos/test_logo.jpeg",
"video": "http://dev.thevariable.com/media/brands/videos/3D463BC3-38B8-4A6F-BE93-3F53E918EC3B-3533-00000118880074BA_1.1.mp4",
"video_thumbnail": "http://dev.thevariable.com/media/brands/video_thumbnails/3D463BC3-38B8-4A6F-BE93-3F53E918EC3B-3533-00000118880074BA_1.1.mp4.jpg",
"links": {
"self": "http://dev.thevariable.com/api/brands/bike-work-day"
},
"status_display": "published",
"video_views": 0
}

这是我的 Backbone 观点:

var TemplateView = Backbone.View.extend({
    templateName: '',
    initialize: function () {
        this.template = _.template($(this.templateName).html());
    },
    render: function () {
        var context = this.getContext(), html = this.template(context);
        this.$el.html(html);
    },
    getContext: function () {
        return {};
    }
});

var HomePageView = TemplateView.extend({
    templateName: '#home-template',
    events: {
        'click video': 'updateCounter',
        'click .video video': 'playVideo',
        'click .sound': 'muteVideo',
        'click .js-open-card': 'openCard'
    },
    initialize: function (options) {
        var self = this;
        TemplateView.prototype.initialize.apply(this, arguments);
        app.collections.ready.done(function () {
            app.brands.fetch({success: $.proxy(self.render, self)});
        });
    },
    getContext: function () {
        return {brands: app.brands || null};
    },
    updateCounter: function (e) {
        var id = $(e.currentTarget).data('id');
        var item = self.app.brands.get(id);
        var views = item.get('video_views');
        var video = this.$('.video video');
        // Only update the counter if the video is in play state
        if (video.prop('paused')) {
            item.save({video_views: views + 1}, {patch: true});
            this.render();
        }
    },
    playVideo: function () {
        var video = this.$('.video video');
        if (video.prop('paused')) {
          video[0].play();
        } else {
          video.get(0).pause();
        }
    },
    muteVideo: function (e) {
        e.preventDefault();
        var video = this.$el.parent().find('video');
        video.prop('muted', !video.prop('muted'));
        this.$('.sound').toggleClass('is-muted');
    },
    openCard: function (e) {
        e.preventDefault();
        this.$el.toggleClass('is-open');
        this.$el.closest('.card-container').toggleClass('is-open');
    }
});

还有我的 Backbone 模特:

var BaseModel = Backbone.Model.extend({
    url: function () {
        var links = this.get('links'),
            url = links && links.self;
        if (!url) {
            url = Backbone.Model.prototype.url.call(this);
        }
        return url;
    }
});

app.models.Brand = BaseModel.extend({
    idAttributemodel: 'slug'
});

var BaseCollection = Backbone.Collection.extend({
    parse: function (response) {
        this._next = response.next;
        this._previous = response.previous;
        this._count = response.count;
        return response.results || [];
    },
    getOrFetch: function (id) {
        var result = new $.Deferred(),
            model = this.get(id);
        if (!model) {
            model = this.push({id: id});
            model.fetch({
                success: function (model, response, options) {
                    result.resolve(model);
                },
                error: function (model, response, options) {
                    result.reject(model, response);
                }
            });
        } else {
            result.resolve(model);
        }
        return result;
    }
});

app.collections.ready = $.getJSON(app.apiRoot);
app.collections.ready.done(function (data) {
    app.collections.Brands = BaseCollection.extend({
        model: app.models.Brand,
        url: data.brands
    });
    app.brands = new app.collections.Brands();
});

只需在模型上增加该属性并保存即可。

var views = model.get('video_views');

model.set({video_views: views + 1});

model.save();