【问题标题】:Using toJSON on a ember.js record, is setting one of the attributes to null在 ember.js 记录上使用 toJSON,将属性之一设置为 null
【发布时间】:2013-12-05 02:09:41
【问题描述】:

我一直在搞乱ember.js todoMVC 的例子。完成并工作得很好,但为了了解更多信息,我开始修改它。

我从这里更新了模型:

Todos.Todo = DS.Model.extend({
   title: DS.attr('string'),
   isCompleted: DS.attr('boolean'),
});

到这里:

Todos.Todo = DS.Model.extend({
    title: DS.attr('string'),
    isCompleted: DS.attr('boolean'),
    date: DS.attr('date')
}); 

(我也在使用 ember-data)。

添加到模板以便能够输入日期,然后将createTodo 的控制器操作更新为:

actions: {
    createTodo: function(){
        var title = this.get('newTitle');
        var date = this.get('newDate');     

        if(!title.trim()){
            return;
        }

        var todo = this.store.createRecord('todo',{
            date: date,
            title: title,
            isCompleted: false              
        });

        //this clears the input field value
        this.set('newTitle', '');
        this.set('newDate', '');

        //and save the instance of the model.
        todo.save();
    },
//...More code

太好了,一切正常,所以我使用localstorage adapter 将其保存到localstorage。

这是问题所在,日期没有保存到localstorage,这是因为适配器中使用了toJSON 和serialize 方法。

适配器具体是这样做的:

    _addRecordToNamespace: function (namespace, record) {
            var data = record.serialize({includeId: true});
            namespace.records[data.id] = data;
    }

它采用作为记录一部分的_data 子对象,如下所示:

//taken from the chrome inspector 
_data: Object
  __ember1386208719445_meta: Meta
  date: "12/11/2013"
  isCompleted: false
  title: "testing something"
  __proto__: Object

然后返回:

Object {title: "testing something", isCompleted: false, date: null}

toJSON 返回相同的内容。

所以 TLDR && 问题:

为什么 toJSON 和 serialize 方法将我的 date 设置为 null,而它显然有一个值,并且该值是一个字符串?

【问题讨论】:

    标签: javascript html ember.js ember-data to-json


    【解决方案1】:

    这是因为你说它是日期类型,但是你将它设置为一个字符串,所以当 ember 数据试图序列化它时它很困惑,因为它需要一个日期,所以它会返回 null。

    serialize: function(date) {
      if (date instanceof Date) {
        var days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
        var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
    
        var pad = function(num) {
          return num < 10 ? "0"+num : ""+num;
        };
    
        var utcYear = date.getUTCFullYear(),
          utcMonth = date.getUTCMonth(),
          utcDayOfMonth = date.getUTCDate(),
          utcDay = date.getUTCDay(),
          utcHours = date.getUTCHours(),
          utcMinutes = date.getUTCMinutes(),
          utcSeconds = date.getUTCSeconds();
    
    
        var dayOfWeek = days[utcDay];
        var dayOfMonth = pad(utcDayOfMonth);
        var month = months[utcMonth];
    
        return dayOfWeek + ", " + dayOfMonth + " " + month + " " + utcYear + " " +
             pad(utcHours) + ":" + pad(utcMinutes) + ":" + pad(utcSeconds) + " GMT";
      } else {
        return null;
      }
    }
    

    【讨论】:

    • 是的,一旦我看到将 date 类型从 DS.attr() 中取出来修复它,我就去查看了 ember-data 的来源并看到了你发布的内容。
    【解决方案2】:

    您的日期格式无效。尝试“2013-02-07T16:44:57”而不是“12/11/2013”​​。

    【讨论】:

    • 格式无关紧要。这是一个字符串。但是为了彻底起见,我尝试了您的建议,但并没有解决问题。
    • 是的,它是一个字符串,但是您的 DS.attr 将其指定为日期,因此它需要某种格式。尝试编辑我的答案。
    • 很高兴了解 DS.attr,但我认为这不是问题所在。如果我在 ember 检查器中查看记录,日期就在那里,只有当我刷新页面并且它必须从适配器检索记录时,日期才不再存在。我可以通过将记录分配给窗口对象来重复错误,然后在 chrome 检查器中调用serialize() 或toJSON()。
    • 你有机会组装一个 jsBin 吗?
    • 您的最后一条评论让我开始思考,我从DS.attr() 中删除了“日期”类型规范,现在它可以工作了。
    猜你喜欢
    • 2021-03-23
    • 1970-01-01
    • 1970-01-01
    • 2018-09-02
    • 1970-01-01
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多