在负载上实例化Ember模型的最佳实践(LocalStorage)

时间:2014-10-15 12:57:57

标签: ember.js ember-data

我正在创建一个使用带产品和购物袋的ember的基本商店。我使用LocalStorage作为购物袋的适配器,因此用户可以回到他们之前添加的产品的购物车。在任何时候,应该只有一个购物袋。现在,我在activate的应用程序路径中设置了一个检查器,看看是否已经保存了一个包。如果没有,请创建一个。

我还想正确设置模型,以便在控制器和模板中使用它。这是我的申请路线“

var ApplicationRoute = Ember.Route.extend({
  activate: function() {
    var store = this.store;
    store.find('bag').then(function(bags) {
      var existing_bag = bags.get('firstObject');
      // If there isn't already a bag instantiated, make one and save it
      if(typeof existing_bag === 'undefined') {
        var new_bag = store.createRecord('bag');
        new_bag.save();
      }
    });
  },
  model: function() {
    return this.store.find('bag');
  },
  setupController: function(controller,model) {
    controller.set('content', model);
  }
});

export default ApplicationRoute; 

这是我的包包型号:

import DS from 'ember-data';
import Ember from "ember";

export default DS.Model.extend({
  products: DS.hasMany('product', {async: true}),
  bagProducts: DS.hasMany('bagProduct', {async: true}),
  productCount: Ember.computed.alias('products.length')
});

在我的控制器中,我想检查包里是否有产品,这样我就可以显示产品数量:

import Ember from "ember";

export default Ember.ArrayController.extend({
  bag: Ember.computed.alias("content"),
  cartHasProducts: function() {
    var bag = this.get('bag').objectAt('0');
    return bag.get('productCount') > 0;
  }.property('content.@each.productCount')
});

我的模板:

<div id="bag" class="js-btn" {{action "showModal" 'bag-modal' model}}>
  <i class="icon ion-bag"></i>
  <p class="label">Your Bag</p>
  {{#if controller.cartHasProducts}}
    <div class="count">
      <span>{{productCount}}</span>
    </div>
  {{/if}}
</div>

这可行,但只有在我使用objectAt('0')获取包的第一个实例之后。 content不应该只返回行李的一个实例吗?有没有办法设置模型只返回一个当前实例?我究竟做错了什么?

我非常感谢你的帮助!

1 个答案:

答案 0 :(得分:2)

这可能是一个解决方案: http://codepen.io/szines/pen/Aufmp?editors=101

(也应该使用LocalStorage,上面的示例使用FixtureAdapter。)

您可以使用RSVP在商店下载这两个型号,在afterModel中,您可以检查,包已经存在与否。如果没有,您可以创建一个。

您可以在setupController中映射主模型和辅助模型,这样它们就会存在于Controller和视图中。

App.IndexRoute = Ember.Route.extend({
  model: function() {
    return Ember.RSVP.hash({
      bagModel:        this.store.find('bag'),
      productList:     this.store.find('product')
    })
  },

  afterModel: function(model, transition) {
    if (model.bagModel.get('length') < 1) {
      model.bagModel = this.store.createRecord('bag');
    }
  },

  setupController: function(controller, model) {
    var productList = model.productList,
        bagModel    = model.bagModel;
    model = model.bagModel;
    this._super(controller, model);
    controller.set('productList', productList);
  }
});

因为你只有一个包作为主模型,所以如果你使用ObjectController会更好。

控制器和型号:

App.IndexController = Ember.ObjectController.extend({

  productCount: Ember.computed.alias('model.products.length'),

  actions: {
    addProduct: function(product) {
      this.get('model').get('products').pushObject(product);
    }
  }
});

App.Bag = DS.Model.extend({
  products: DS.hasMany('product', {async: true}),
});

App.Product = DS.Model.extend({
  name: DS.attr('string'),
});

App.Bag.FIXTURES = [];

App.Product.FIXTURES = [
  {id: 1, name: 'First Product'},
  {id: 2, name: 'Second Product'},
  {id: 3, name: 'Third Product'}
]

和索引模板:

Number of products: {{productCount}}

{{#each productList}}
  <button {{action 'addProduct' this}}>Add {{name}}</button>
{{/each}}