backbone.js:将项目添加到当前项目之后的集合中

发布于 2024-12-25 14:44:35 字数 3562 浏览 0 评论 0原文

我正在尝试创建一个带有主干的发票行列表,其中一个按钮/事件是,当您在现有行上单击“添加”时,它应该在单击“添加”按钮的正下方添加一个新行。

首先,我不确定是否应该在 InvoiceItemView 或 InvoiceItemListView 中处理此事件,其次,我不确定如何执行此操作。有人可以帮助我吗?

我尝试了这个:

$(function(){

// Invoice row
var InvoiceItem = Backbone.Model.extend({

    // Set default values
    defaults : {
        name: "",
        quantity: 1,
        price: "",
        total: ""
    },

    // Ensure each item has at least a quantity of one
    initialize: function() {
        this.set({ "quantity" : this.defaults.quantity });
    },

    // Delete item (row) from invoice
    clear: function() {
        this.destroy();
    }        

});

// Collection of Invoice Items ( rows )
var InvoiceItemList = Backbone.Collection.extend({

    // Colelction's model
    model: InvoiceItem,

    // Use localStorage to save data
    localStorage: new Store("invoices-backbone"),

    // Calculate invoice totals
    calculate_totals: function() {
        alert('arvutus');  
    },

    // Generate next item order number
    nextOrder: function() {
        if (!this.length) return 1;
        return this.last().get('order') + 1;
    }

});

// Create a global colelction of Invoice Rows
var InvoiceItems = new InvoiceItemList;

// Invoice Item View
var InvoiceItemView = Backbone.View.extend({

    // it's a tr tag
    tagName: 'tr',

    // Cache the template
    template: _.template($('#invoiceitem-template').html()),

    events: {
        "click .remove"     : "clear",
        "click .add"        : "addAfter"
    },

    initialize: function() {
        _.bindAll(this, 'render', 'addAfter', 'remove');
        this.model.bind('change', this.render);
        this.model.bind('destroy', this.remove);
        this.render();
    },

    // Render the contents
    render: function() {
        $(this.el).html(this.template(this.model.toJSON()));
        $(this.el).attr('id', 'item-' + this.model.get('order'));
        return this;
    },

    // Remove and destroy the item
    clear: function() {
        this.model.clear();
    },

    // Add new item
    addAfter: function(ItemId) {
        var view = new InvoiceItemView({model: InvoiceItem});
        this.$("tbody tr#item"+ItemId).after(view.render().el);
    }

});

// Invoice Item List View
InvoiceItemListView = Backbone.View.extend({

    // Bind to existing DOM element
    el: $("#items"),

    // Template for displaying totals
    totalsTemplate: _.template($('#totals-template').html()),

    // Kick-off (load from localStorage as well)
    initialize: function() {
        _.bindAll(this, 'addOne', 'render');

        InvoiceItems.bind('add', this.addOne);

        InvoiceItems.fetch();

        InvoiceItems.create(this.newAttributes());
        InvoiceItems.create(this.newAttributes());
        InvoiceItems.create(this.newAttributes());

        this.render();
    },

    // Re-render the totals
    render: function() {
        this.$('#totals').html(this.totalsTemplate({
            total: this.total
        }));
    },

    // Generate the attributes for a new Invoice Item.
    newAttributes: function() {
        return {
            name: '',
            price: '',
            total: '',
            order: InvoiceItems.nextOrder()
        };
    },

    // Add a single invoice item to the list
    addOne: function(InvoiceItem) {
        var view = new InvoiceItemView({model: InvoiceItem});
        this.$("tbody").append(view.render().el);
    }

});

var iView = new InvoiceItemListView;

});

但我收到错误:this.model.toJSON 不是函数

I'm trying to create a invoice rows list with backbone and one of the buttons/events is that when You click "add" on an existing row, it should add a new row right below the one that's "add" button was clicked.

First, I am not sure if I should handle this event in the InvoiceItemView or InvoiceItemListView, and second, I am not sure how to do this. Can anybody help me?

I tried this:

$(function(){

// Invoice row
var InvoiceItem = Backbone.Model.extend({

    // Set default values
    defaults : {
        name: "",
        quantity: 1,
        price: "",
        total: ""
    },

    // Ensure each item has at least a quantity of one
    initialize: function() {
        this.set({ "quantity" : this.defaults.quantity });
    },

    // Delete item (row) from invoice
    clear: function() {
        this.destroy();
    }        

});

// Collection of Invoice Items ( rows )
var InvoiceItemList = Backbone.Collection.extend({

    // Colelction's model
    model: InvoiceItem,

    // Use localStorage to save data
    localStorage: new Store("invoices-backbone"),

    // Calculate invoice totals
    calculate_totals: function() {
        alert('arvutus');  
    },

    // Generate next item order number
    nextOrder: function() {
        if (!this.length) return 1;
        return this.last().get('order') + 1;
    }

});

// Create a global colelction of Invoice Rows
var InvoiceItems = new InvoiceItemList;

// Invoice Item View
var InvoiceItemView = Backbone.View.extend({

    // it's a tr tag
    tagName: 'tr',

    // Cache the template
    template: _.template($('#invoiceitem-template').html()),

    events: {
        "click .remove"     : "clear",
        "click .add"        : "addAfter"
    },

    initialize: function() {
        _.bindAll(this, 'render', 'addAfter', 'remove');
        this.model.bind('change', this.render);
        this.model.bind('destroy', this.remove);
        this.render();
    },

    // Render the contents
    render: function() {
        $(this.el).html(this.template(this.model.toJSON()));
        $(this.el).attr('id', 'item-' + this.model.get('order'));
        return this;
    },

    // Remove and destroy the item
    clear: function() {
        this.model.clear();
    },

    // Add new item
    addAfter: function(ItemId) {
        var view = new InvoiceItemView({model: InvoiceItem});
        this.$("tbody tr#item"+ItemId).after(view.render().el);
    }

});

// Invoice Item List View
InvoiceItemListView = Backbone.View.extend({

    // Bind to existing DOM element
    el: $("#items"),

    // Template for displaying totals
    totalsTemplate: _.template($('#totals-template').html()),

    // Kick-off (load from localStorage as well)
    initialize: function() {
        _.bindAll(this, 'addOne', 'render');

        InvoiceItems.bind('add', this.addOne);

        InvoiceItems.fetch();

        InvoiceItems.create(this.newAttributes());
        InvoiceItems.create(this.newAttributes());
        InvoiceItems.create(this.newAttributes());

        this.render();
    },

    // Re-render the totals
    render: function() {
        this.$('#totals').html(this.totalsTemplate({
            total: this.total
        }));
    },

    // Generate the attributes for a new Invoice Item.
    newAttributes: function() {
        return {
            name: '',
            price: '',
            total: '',
            order: InvoiceItems.nextOrder()
        };
    },

    // Add a single invoice item to the list
    addOne: function(InvoiceItem) {
        var view = new InvoiceItemView({model: InvoiceItem});
        this.$("tbody").append(view.render().el);
    }

});

var iView = new InvoiceItemListView;

});

But I am getting an error: this.model.toJSON is not a function

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

江挽川 2025-01-01 14:44:35

问题在于您创建新的 InvoiceItemView 的位置。您必须创建 InvoiceItem 的新实例

// Add new item
addAfter: function(ItemId) {
    var view = new InvoiceItemView({model: new InvoiceItem()});
    this.$("tbody tr#item"+ItemId).after(view.render().el);
}

The problem is where you create your new InvoiceItemView. You have to create a new instance of InvoiceItem

// Add new item
addAfter: function(ItemId) {
    var view = new InvoiceItemView({model: new InvoiceItem()});
    this.$("tbody tr#item"+ItemId).after(view.render().el);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文