【问题标题】:Meteor Storing and Retrieving Custom Objects in SessionMeteor 在会话中存储和检索自定义对象
【发布时间】:2015-09-14 04:50:53
【问题描述】:

我创建了一个自定义购物车对象并将其放入lib 文件夹中。

ShoppingCart = function ShoppingCart() {
  this.Items = new Array();
  this.grandTotal = 0.00;
}

ShoppingCart.prototype.addItem = function(Item){
  this.Items.push(Item);
  this.Items.sort();
  this.calculateTotal();
}

我在页面created阶段初始化了购物车并将其存储为Session.set('shoppingCart')

Template.loginStatus.created = function() {
  Session.set('loginShown',false);
  if(!Session.get('shoppingCart')){ //set default if session shopping cart not exist
    var cart = new ShoppingCart();
    Session.setDefault('shoppingCart',cart);
  }

那么当用户点击添加商品到购物车时,就会触发这个逻辑:

var cart = Session.get('shoppingCart');
cart.addItem(item);
Session.set('shoppingCart',cart);

不知何故,它不起作用。当我查看 chrome 控制台广告时,它显示undefined is not a function,指向cart.addItem(item) 行。如果我把它改成这个,它会起作用,但当然,因为每次创建新的购物车,我都无法在购物车中累积物品。

var cart = new ShoppingCart();
cart.addItem(item);
Session.set('shoppingCart',cart);

我应该如何正确存储和检索会话中的对象?看起来从 Session.get() 返回的对象不知何故不被视为 ShoppingCart。我错过了任何类型转换吗?

【问题讨论】:

  • Session 只能存储支持 EJSON 的对象。您的 ShoppingCart 不支持 EJSON。我不知道这个问题的最佳解决方案,所以我把它留给另一个人。
  • @PeppeL-G 是否可以将其类型转换回ShoppingCart。在 ASP.NET 中可以这样做,那么 Javascript 怎么样?

标签: javascript jquery meteor


【解决方案1】:

正如@Peppe L-G 提到的,您只能将 EJSON 存储在 Session 中。要存储您的自定义对象,您需要能够手动将其转换为 EJSON 和从 EJSON 转换。示例:

_.extend(ShoppingCart, {
  fromJSON: function(json) {
    var obj = new ShoppingCart();
    obj.grandTotal = json.grandTotal;
    obj.Items = json.Items;
    return obj;
  },
});

_.extend(ShoppingCart.prototype, {
  toJSON: function() {
    return {
      grandTotal: this.grandTotal,
      Items: this.Items,
    };
  },
});

然后就可以保存到Session了:

Session.set('shoppingCart', cart.toJSON());

并恢复:

ShoppingCart.fromJSON(Session.get('shoppingCart'));

【讨论】:

  • 不能以某种方式使用EJSON.addType吗?
  • 有可能,但并不容易。您需要将factory 方法传递给addType,与上面的fromJSON 相同。此外,ShoppingCart 需要实现toJSONValue。所以你仍然需要定义这两个方法。但是您说得对,这是一种更好的方法,因为您将能够更轻松地存储诸如数组 ShoppingCarts 之类的东西。见documentation
  • 只是想添加对象数组,即[{"param":"value1"},{"param":"value2"},...]JSON.stringify,如果有人对此感到好奇。
【解决方案2】:

我遇到了同样的问题。本质上,Meteor 会话(和集合)只能存储 EJSON 类型,因此您的 ShoppingCart 自定义类型会从会话中检索为普通对象。

虽然您可以手动在 EJSON 之间进行转换,但您最终可能需要在很多不同的地方重复执行此操作。如果您的 ShoppingCart 是另一个对象的成员,您还必须手动转换该成员。最好使用 EJSON.addType 告诉 Meteor 如何在您存储或检索该类型对象的任何地方自动处理它。

这里有一个很棒的演示:https://www.eventedmind.com/feed/meteor-create-a-custom-ejson-type。完整的文档也在这里:http://docs.meteor.com/#/full/ejson。但一个简短的版本是这样的:

  1. 为您的自定义类型添加一个名为 typeName 的方法:

    ShoppingCart.prototoype.typeName = function(){ 返回“购物车”; };
  2. 添加另一个名为 toJSONValue 的方法:

    ShoppingCart.prototype.toJSONValue = function(){ /* 返回对象的 JSON 兼容版本 */ };
  3. 最后,将自定义类型添加到 EJSON 中:

    EJSON.addType("ShoppingCart", function fromJSONValue(value){ /* 从 JSON 对象“值”返回您自定义类型的对象 */ };

注意:第 1 步和第 3 步中的“类型名称”必须完全匹配。

【讨论】:

    猜你喜欢
    • 2014-01-17
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 2018-05-28
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多