初始加载后,在项目视图中未定义骨干模型

时间:2012-12-12 03:37:59

标签: javascript backbone.js model undefined onchange

我是一个完整的Backbone noob,所以忍受我...

我有一个由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>

有什么想法吗?谢谢!

1 个答案:

答案 0 :(得分:2)

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

  1. 它处理集合的“添加”事件
  2. 它处理点击“#addIncome”按钮
  3. 第一个发送您期望的参数(添加模型),但第二个不发送 - 它发送单击的元素(#addIncome)。


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

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

    这应创建一个新模型并将其传递给'addOne`:

    addNew: function(e) {
        e.preventDefault();
        this.addOne( new IncomeModel() );
    }