为什么我在 products.index 中看到一个空产品?

Why do I see an empty product in products.index?

这是我的 products.index 的样子:

当我点击 "Create product" link 时。它把我送到 /products/new。我在那里看到一个表格,但我没有提交它,而是单击 "Cancel" 按钮。我的控制器中有一个将我重定向到 products.index 页面的操作。

  actions: {
    cancel: function() {
      this.transitionToRoute('products.index');

      return false;
    }
  }

/products中,我看到:

这是一个空产品... API 中的数据库没有产品。我刷新页面,空产品消失了。这是怎么回事?

完整代码:

// app/routes/products/index.js
import Ember from 'ember';

export default Ember.Route.extend({
  model: function() {
    return this.store.find('product');
  }
});

// app/routes/products/new.js
import Ember from 'ember';

export default Ember.Route.extend({
  model: function() {
    return this.store.createRecord('product');
  },
});

// app/controllers/select-addresses/new.js
export default Ember.ObjectController.extend({
  actions: {
    cancel: function() {
      this.transitionToRoute('products.index');

      return false;
    }
  }
});

// app/templates/products/index.hbs
<h1>Products index</h1>

<p>{{#link-to 'products.new'}}Create product{{/link-to}}</p>

<ul>
  {{#each}}
  <li>
    {{#link-to 'products.show' this}}<strong>{{name}}</strong>{{/link-to}}
    <br />Description: {{description}}
    <br />Amount in cents: {{amountInCents}}
    <br />{{link-to 'Edit' 'products.edit' this}} &middot; <a href="#" {{action "delete" this}}>Delete</a>
    <br /><br />
  </li>
  {{/each}}
</ul>

// app/templates/products/new.hbs
<h1>Add a new friend</h1>

<form {{action "save" on="submit"}}>
  <p>
    <label>Name:
      {{input value=name}}
    </label>

    {{#each error in errors.name}}
      <br />{{error.message}}
    {{/each}}
  </p>

  <p>
    <label>Description:
      {{input value=description}}
    </label>

    {{#each error in errors.description}}
      <br />{{error.message}}
    {{/each}}
  </p>

  <p>
    <label>Amount in cents:
      {{input value=amountInCents}}
    </label>

    {{#each error in errors.amountInCents}}
      <br />{{error.message}}
    {{/each}}
  </p>

  <p>
    <label>Status:
      {{input value=status}}
    </label>

    {{#each error in errors.status}}
      <br />{{error.message}}
    {{/each}}
  </p>

  <input type="submit" value="Save"/>
  <button {{action "cancel"}}>Cancel</button>
</form>

{{outlet}}

我的猜测(作为非Ember专家):

在您的 Ember.Route.extend 中,您为模型发出了对 store.createRecord 的调用。通过这种方式,您可以向商店添加一个空产品。当您取消表单时,您不会从商店中删除虚拟产品,因此当您加载索引视图时它仍然存在。

所以在产品索引路线中,我将return this.store.find('product');更改为return this.store.find('product', {});

问题消失了!我不确定这是否是正确的方法,但到目前为止没有问题!

// app/routes/products/index.js
import Ember from 'ember';

export default Ember.Route.extend({
  model: function() {
    // Before
    // return this.store.find('product');

    // After
    return this.store.find('product', {});
  }
});

更新:在转换之前执行 this.store.unloadAll('product'); 似乎也有效。这似乎是一个更自然的解决方案。根据这个拉取请求 https://github.com/emberjs/data/pull/1714

但是,单击浏览器上的后退按钮,仍然呈现空产品。

所以基本上:

// app/routes/products/index.js
import Ember from 'ember';

export default Ember.Route.extend({
  model: function() {
    return this.store.find('product');
  }
});

// app/controllers/select-addresses/new.js
export default Ember.ObjectController.extend({
  actions: {
    cancel: function() {
      this.store.unloadAll('product');
      this.transitionToRoute('products.index');

      return false;
    }
  }
});

使用ember-data-route然后你应该

{{#each product in model}}
  {{#unless product.isNew}}
    {{product.name}}
  {{/unless}}
{{/each}}

如果您不想使用 ember-data-route,您可以随时使用 resetController 并执行 model.deleteRecord()

// app/routes/products/new.js
import Ember from 'ember';

export default Ember.Route.extend({
  model: function() {
    return this.store.createRecord('product');
  },

  resetController: function (controller, isExiting) {
    var model = controller.get('model');

    if (isExiting && model.get('isNew')) {
      model.deleteRecord()
    }
  }
});

要获得更深入的版本,请参阅 ember-data-route is doing.

您可以使用 deactivate 路由挂钩从存储中删除新的(非持久化)记录。

// app/routes/products/new.js
import Ember from 'ember';

export default Ember.Route.extend({
  model: function() {
    return this.store.createRecord('product');
  },
  deactivate: function () {
    var model = this.modelFor('products.new');
    if (model.get('isNew')) {
      model.destroyRecord();
    }
  }
});

当您在没有使用 .save() 保存记录的情况下离开路线时,它会破坏商店中的记录,因此不会在模板中呈现。