Backbone.js两个模型相互影响

时间:2013-03-13 16:19:18

标签: javascript jquery model-view-controller backbone.js underscore.js

我有一个表,它的行是集合中的模型,每行有两列输入,每小时和小时的速率,模型也有属性total,基本上只是rate_per_hour*hours,并且它会随着用户更改小时数或每小时费率而更新。您也可以添加新行并删除它们。我相信,我设法做了正确的骨干方式。

现在第一部分我不确定,我需要一个包含小时和总和的div,我还设法使用一个函数(它基本上只通过集合中的模型循环,总和)他们的属性,然后使用jquery更新我的div),在模型上更改事件,在设置新属性后,调用此函数。它在所有视图/集合/模型之外。不确定这是否是正确的方法,但它确实有效。

现在是我失败的最糟糕的部分,从一开始就意识到我的代码可能是错误的。在该div下,总计是另一个输入,称为折扣,它应该做的是计算折扣百分比((value of discount/my total sum)*100),然后更新表中的费率,以便显示旧的和应用折扣的一个。

此处存在实际问题:

我不知道的是如何将底部部分(总计和折扣 - 见截图)与上部连接,如果底部部分是另一个模型,具有属性总数,折扣和小时数,并拥有它自己的查看而不是一个简单的div?但那么它将如何运作,一个模型(折扣)如何影响集合中的模型,反之亦然,添加一行需要影响总计和折扣百分比?

这是截图,它应该是如何工作的,只有一个工作的jquery-only版本,我还没有使用骨干。

http://i.imgur.com/J3uyilH.png

如果请求也会发布代码,但现在我试图通过使用jquery事件来解决它,我自己的简单对象包含那些总数和shizzle wizzle。

1 个答案:

答案 0 :(得分:1)

似乎您所遇到的是建模数据的问题。有时退后一步并问自己“我正在使用的是什么东西?”。

您提到的每一行似乎都代表一个“活动”(每个都有一个名称和速率)。你也有这些活动的集合,这很好。现在你可以问,“整个ui(由它的整个屏幕截图代表)代表什么样的东西?”。如果我们将这个ui称为ActivitiesView,它可以监听更新集合的UI交互(更改字段)。集合更改后,会触发视图以使用更新的总计重新呈现。

在此示例中,集合上的折扣字段只是一种便利,并由集合用于更新其子项。

var Activity = Backbone.Model.extend({
    defaults: { discount: 0 }
});

var ActivityCollection = Backbone.Collection.extend({
    initialize: function () {
        this.on("change:discount", this.updateDiscounts, this);
    },
    model: activity,
    totalAmount: function () { /* ...iterate over items, return total amount, factoring in total */ },
    totalHours: function () { /* ...iterate over items, return total hours... */ },
    updateDiscounts: function (discount) { /* ...iterate over items, updating each item's discount */}
});

var ActivitiesView = Backbone.View.extend({

  events: {
    "change input.discount": "applyDicsounts"
  },

  initialize: function() {
    this.listenTo(this.collection, "change", this.render);
    this.listenTo(this.model, "change", this.render);
  }

  render: function() {
    this.$el.find('.totalAmount').text(this.collection.totalAmount());
    this.$el.find('.totalHours').text(this.collection.totalHours());  
  },

  applyDicsounts: function (e) {
    var new_discount = e.target.value; // should probably validate this
    this.collection.set({ discount: new_discount });
  }

});

var myCollection = new ActivityCollection();
var myActivitiesView = new ActivitiesView({ collection: myCollection });