EmberJS:由于未正确删除记录,引导模式拒绝重新打开



目标:

我在这里真正想完成的事情是了解如何干净地使用模型记录。 在这种特殊情况下,这些记录是一种"一次性"。 如果模态在没有保存的情况下关闭,那么它们应该从内存中清除......一旦记录被保存到服务器,也不需要保留客户端存储的RE记录。

描述:

我创建了一个按钮操作,该操作转换为"付款"路由,该路由在 Bootstrap 模态中呈现。

此路由创建"付款"记录,并提取付款可以应用于的可用"债务"列表。

App.PaymentRoute = Ember.Route.extend({
  model: function() {
    console.log('( Router: Model Hook )--------------------)');
    return this.store.createRecord('payment');
  },
  afterModel: function() {
    console.log('( Router: AfterModel Hook )--------------------)');
    var route = this;
    return Ember.RSVP.hash({
      debt_list: this.store.find('debt', { account_id: 36, page_size: 100, page_number: 1 })
    }).then(function(hash) {
      route.setProperties({
        account_id: 36,
        debt_list: hash.debt_list
      });
    });
  },
  setupController: function(controller, model) {
    console.log('( Router: SetupController Hook )--------------------)');
    this._super(controller, model);
    controller.setProperties({
      account_id: this.get('account_id'),
      debt_list: this.get('debt_list')
    });
  },
});

关闭模式应删除当前记录并转换回索引...

actions: {
    removeModal: function() {
      this.currentModel.deleteRecord();
      this.transitionTo('index');
      return true;
    }
  }

当第二次点击付款按钮时,它"应该"创建一个新的付款记录......而是发生错误,因为上一条记录未正确清除?

我成功地在此JSBin中重新创建了该问题

我是否正确创建和删除记录?

旁注:

我已经在所有路由和控制器方法上设置了console.log()...我注意到setupController在第二次打开尝试时没有开火......此外,我的控制器 cp 和观察者在初始化过程中多次触发......我不知道这是否导致了问题?

问题似乎是this.store.find('debt', { account_id: 36, page_size: 100, page_number: 1 })

因为 ember 数据会在查询完成后将项目加载到存储中,并且控制器绑定到该数组,因此当它更改时,将触发所有观察者。

所以setDebtPayments被调用,(在setupController之前(,试图做model.set('payment_debts', paymentDebts);此时已经被破坏了。

我设法通过在调用removeModal时创建新的付款记录来解决此问题(次优(。

另一种选择是检查控制器是否装饰了一个模型,然后再对其进行任何操作:http://jsbin.com/ziket/8

我认为您实际上不想"删除"记录。您要做的是回滚对它所做的任何更改,然后卸载它。 我会在路线上的willTransition钩中执行此操作,因此无论您如何离开路线,模型都将被卸载。

法典:

willTransition: function(transition) {
  var model = this.currentModel;
  var debt_list = get(this, 'debt_list');
  var store = this.store;
  // dispose of models after views have been finalised 
  Ember.run.once(function() {
    if (model) {
      model.rollback();
      store.unloadRecord(model);
    }
    if (debt_list) {
      debt_list.forEach(function(debt) {
        debt.rollback();
        store.unloadRecord(debt);
      });
    }
  }
}

更新:重要的是从余烬运行循环中卸载记录,以便在从模型下撕下模型之前,让绑定到这些记录的任何视图都有机会被拆除。 这就是为什么模型处置是在 Ember.run.once() .

另一个观察结果是,您应该能够使用 RSVP.hashmodel钩子中启动debt_list请求。 因此,将它们放在一起,您的路线应如下所示:

var get = Ember.get, set = Ember.set;
App.PaymentRoute = Ember.Route.extend({
  model: function(params, transition, queryParams) {
    return Ember.RSVP.hash({
      content: this.store.createRecord('payment'),
      debt_list: this.store.find('debt', { account_id: 36, page_size: 100, page_number: 1 })
    });
  },
  setupController: function(controller, hash) {
    if (controller && hash) {
      controller.setProperties(hash);
      set(controller, 'account_id', 36);
    }
  },
  actions: {
    willTransition: function(transition) {
      var hash = this.currentModel;
      var store = this.store;
      // tell controller to reset/cleanup - you should set any
      // model related properties ie 'content'/'model' and 'debt_list'
      // to null/default values.
      this.controller.reset();
      if (hash) 
        // dispose of models after views have been finalised 
        Ember.run.once(function() {
          hash.content.rollback();
          store.unloadRecord(hash.content);
          hash.debt_list.forEach(function(debt) {
            debt.rollback();
            store.unloadRecord(debt);
          });
        });
      }
    }
  }
});

我在这里更新了您的 JSBin,因此它可以完美运行,模型已从商店中正确删除。

相关内容

最新更新