2

我是一个完全的骨干菜鸟,所以请耐心等待……</p>

我有一个由 json 数据填充的表。当我加载页面时,表格会正确呈现数据,并且我能够更新现有模型。

当我尝试使用表外的“添加”按钮向表中添加新模型和行时,出现此错误:

TypeError: 'undefined' 不是一个函数(评估 'this.model.on('change', this.render, this)')

它似乎打破了我的 IncomeView 初始化功能,但我无法为我的生活找出原因。

window.IncomeView = Backbone.View.extend({
  tagName: 'tr',
  className: 'income-row',
  template: _.template($('#income-template').html()),
  events: {
    'change .name': 'updateName',
    'change .cash': 'updateCash',
    'change .qty': 'updateQty',
    'change .recur': 'updateRecur',
    'change .start': 'updateStart',
    'click .ss-subtract': 'clear'
  },
  initialize: function() {
    this.model.on('change', this.render, this);
    this.model.on('destroy', this.clear, this);
  },
  render: function() {
    var attributes;
    attributes = this.model.toJSON();
    this.$el.html(this.template(attributes));
    this.$('.cash').formatCurrency();
    return this;
  },
  remove: function() {
    this.$el.remove();
  },
  updateName: function(e) {
    this.model.updateName(e);
  },
  updateCash: function(e) {
    this.model.updateCash(e);
  },
  updateQty: function(e) {
    this.model.updateQty(e);
  },
  updateRecur: function(e) {
    this.model.updateRecur(e);
  },
  updateStart: function(e) {
    this.model.updateStart(e);
  },
  clear: function() {
    this.model.clear();
    return false;
  }
});

这是我的收藏视图:

window.IncomeTallyView = Backbone.View.extend({
  el: $('#incomeTable'),
  events: {
    'click #addIncome': 'addOne'
  },
  initialize: function() {
    this.collection.on('add', this.addOne, this);
    this.collection.on('reset', this.addAll, this);
  },
  render: function() {
    this.addAll();
    return this;
  },
  addAll: function() {
    $('#income').empty();
    this.collection.forEach(this.addOne, this);
  },
  addOne: function(incomeItem) {
    var incomeView;
    event.preventDefault();
    incomeView = new IncomeView({
      model: incomeItem
    });
    this.$('#income').append(incomeView.render().el);
  }
});

这是我的模板:

<table class="add" id="incomeTable">
    <thead>
        <tr>
            <th class="move">move</th>
            <th>Name</th>
            <th class="money">Unit cost</th>
            <th class="qty">Qty</th>
            <th class="selects">Recurring?</th>
            <th class="selects startTitle">Starting</th>
        </tr>
    </thead>
    <tbody class="sortable" id="income">
    </tbody>
    <tfoot class="table-nav">
        <tr>
            <td></td>
            <td colspan="5"><a href="#" title="" class="ss-add ss-icon button green" id="addIncome">Add</a> <a href="#" title="" class="ss-subtract ss-icon button red">Remove</a></td>
        </tr>
    </tfoot>
</table>
<script type="text/template" id="income-template">
    <td class="ss-rows"></td>
    <td class="title">
        <label for="<%= _.uniqueId('income-') %>">Name</label>
        <input type="text" name="<%= _.uniqueId('income-') %>" value="<%= name %>" class="name" placeholder="" />
    </td>
    <td class="money">
        <label for="<%= _.uniqueId('unit-cost-') %>">Unit Cost</label>
        <input type="text" name="<%= _.uniqueId('unit-cost-') %>" value="<%= cash %>" class="cash" placeholder="" />
    </td>
    <td class="quantity">
        <label for="<%= _.uniqueId('unit-qty-') %>">Unit Quantity</label>
        <input type="text" name="<%= _.uniqueId('unit-qty-') %>" class="qty" value="<%= qty %>" placeholder="" />
    </td>
    <td class="selects recurring">
        <label for="<%= _.uniqueId('recurring-') %>">Recurring</label>
        <select name="<%= _.uniqueId('recurring-') %>" class="recur">
            <option value="no">No</option>
            <option value="monthly">Monthly</option>
            <option value="yearly">Yearly</option>
        </select>
    </td>
    <td class="starting selects">
        <label for="<%= _.uniqueId('month-') %>">When&hellip;</label>
        <select name="<%= _.uniqueId('month-') %>" class="start">
            <option value="0">January</option>
            <option value="1">February</option>
            <option value="2">March</option>
            <option value="3">April</option>
            <option value="4">May</option>
            <option value="5">June</option>
            <option value="6">July</option>
            <option value="7">August</option>
            <option value="8">September</option>
            <option value="9">October</option>
            <option value="10">November</option>
            <option value="11">December</option>
        </select>
    </td>
</script>

有任何想法吗?谢谢!

4

1 回答 1

2

您已经将该addOne函数作为处理程序连接到两个不同的事件——这可能是一个坏主意,因为参数会根据触发的事件而有所不同。

  1. 它处理集合的“添加”事件
  2. 它处理点击“#addIncome”按钮

第一个发送您期望的参数(添加的模型),但第二个不发送 - 它发送点击的元素(#addIncome)。


我建议为 click 事件添加一个新的处理程序“addNew”:

events: {
    'click #addIncome': 'addNew'
}

这应该创建一个新模型并将其传递给“addOne”:

addNew: function(e) {
    e.preventDefault();
    this.addOne( new IncomeModel() );
}
于 2012-12-12T03:51:18.387 回答