时髦的IE JSON转换

时间:2014-10-16 20:40:04

标签: json angularjs internet-explorer

在IE11中运行我们的AngularJS应用程序时,调试器中的一切看起来都很棒,但是当我们的应用程序将数据编码为JSON以保存到我们的数据库时,我们会得到不好的结果。

我们的应用程序从我们的数据库中获取记录,然后进行一些操作,然后将数据从另一个模型保存回服务器。

以下是我在下面的setAttendanceGetSInfo()函数中从服务器返回的数据:

{"data":{"Start":"2014-10-16T19:36:00Z","End":"2014-10-16T19:37:00Z"},

这是用于"转换数据的代码"到我们模型中的3个属性:

var setAttendanceGetSInfo = function (CourseId, PID) {
    return setAttendanceInfo(CourseId, PID)
    .then(function (result) {
        return $q.all([
            $http.get("../api/Axtra/getSInfo/" + model.event.Id),
            $http.get("../api/Axtra/GetStartAndEndDateTime/" + aRow.Rid)
        ]);
    }).then(function (result) {
        var r = result.data;
        var e = Date.fromISO(r.Start);
        var f = Date.fromISO(r.End);
        angular.extend(model.event, {
            examDate: new Date(e).toLocaleDateString(),
            examStartTime: (new Date(e)).toLocaleTimeString(),
            examEndTime: (new Date(f)).toLocaleTimeString()
        });
        return result.sInfo;
    });
};

fromISO定义为:

(function(){
    var D= new Date('2011-06-02T09:34:29+02:00');
    if(!D || +D!== 1307000069000){
        Date.fromISO= function(s){
            var day, tz,
            rx=/^(\d{4}\-\d\d\-\d\d([tT ][\d:\.]*)?)([zZ]|([+\-])(\d\d):(\d\d))?$/,
            p= rx.exec(s) || [];
            if(p[1]){
                day= p[1].split(/\D/);
                for(var i= 0, L= day.length; i<L; i++){
                    day[i]= parseInt(day[i], 10) || 0;
                };
                day[1]-= 1;
                day= new Date(Date.UTC.apply(Date, day));
                if(!day.getDate()) return NaN;
                if(p[5]){
                    tz= (parseInt(p[5], 10)*60);
                    if(p[6]) tz+= parseInt(p[6], 10);
                    if(p[4]== '+') tz*= -1;
                    if(tz) day.setUTCMinutes(day.getUTCMinutes()+ tz);
                }
                return day;
            }
            return NaN;
        }
    }
    else{
        Date.fromISO= function(s){
            return new Date(s);
        }
    }
})()

查看事件模型数据的屏幕截图:

Screemshot of Model

但是,如果我使用JSON.stringify(model.event)评估事件模型,我会得到:

{\"examDate\":\"?10?/?16?/?2014\",\"examStartTime\":\"?2?:?44?:?00? ?PM\",\"examEndTime\":\"?2?:?44?:?00? ?PM\"}

这是实际存储在DB上的JSON编码数据:

"examDate":"¿10¿/¿16¿/¿2014","examStartTime":"¿2¿:¿36¿:¿00¿ ¿PM","examEndTime":"¿2¿:¿37¿:¿00¿ ¿PM"

这里有什么问题,我该如何解决这个问题?它完全按照Chrome和Firefox的设计工作。我还没有在Safari或早期版本的IE上测试过。

2 个答案:

答案 0 :(得分:0)

对于所有浏览器,日期类的toJSON并未完全相同。

(您可以在此处查看相关问题:Discrepancy in JSON.stringify of date values in different browsers

我怀疑您在Date原型中添加了自定义toJSON,因为您的日期字符串与标准不匹配,而且很可能是您的问题所在。或者,您可以使用上面帖子中推荐的Date toJSON来解决您的问题。

答案 1 :(得分:0)

首先,我将fromISO原型修改为:

(function () {
    var D = new Date('2011-06-02T09:34:29+02:00');
    if (!D || +D !== 1307000069000) {
        Date.fromISO = function (s) {
            var D, M = [], hm, min = 0, d2,
                Rx = /([\d:]+)(\.\d+)?(Z|(([+\-])(\d\d):(\d\d))?)?$/;
            D = s.substring(0, 10).split('-');
            if (s.length > 11) {
                M = s.substring(11).match(Rx) || [];
                if (M[1]) D = D.concat(M[1].split(':'));
                if (M[2]) D.push(Math.round(M[2] * 1000));// msec
            }
            for (var i = 0, L = D.length; i < L; i++) {
                D[i] = parseInt(D[i], 10);
            }
            D[1] -= 1;
            while (D.length < 6) D.push(0);
            if (M[4]) {
                min = parseInt(M[6]) * 60 + parseInt(M[7], 10);// timezone not UTC
                if (M[5] == '+') min *= -1;
            }
            try {
                d2 = Date.fromUTCArray(D);
                if (min) d2.setUTCMinutes(d2.getUTCMinutes() + min);
            }
            catch (er) {
                // bad input
            }
            return d2;
        }
    }
    else {
        Date.fromISO = function (s) {
            return new Date(s);
        }
    }

    Date.fromUTCArray = function (A) {
        var D = new Date;
        while (A.length < 7) A.push(0);
        var T = A.splice(3, A.length);
        D.setUTCFullYear.apply(D, A);
        D.setUTCHours.apply(D, T);
        return D;
    }

    Date.toJSON = function (key) {
        return isFinite(this.valueOf()) ?
               this.getUTCFullYear() + '-' +
             f(this.getUTCMonth() + 1) + '-' +
             f(this.getUTCDate()) + 'T' +
             f(this.getUTCHours()) + ':' +
             f(this.getUTCMinutes()) + ':' +
             f(this.getUTCSeconds()) + 'Z' : null;
    };
})()

然后我添加了moment.js并格式化了存储时的日期:

var SaveAffRow = function () {
    // make sure dates on coursedate and event are correct.
    var cd = model.a.courseDate;
    var ed = model.event.examDate;
    var est = model.event.examStartTime;
    var eet = model.event.examEndTime;
    model.a.courseDate = moment(cd).format("MM/DD/YYYY");
    model.event.examDate = moment(ed).format("MM/DD/YYYY");
    model.event.examStartTime = moment(est).format("MM/DD/YYYY hh:mm A");
    model.event.examEndTime = moment(eet).format("MM/DD/YYYY hh:mm A");
    affRow.DocumentsJson = angular.toJson({a: model.a, event: model.event});

    var aff = {};

    if (affRow.Id != 0) 
        aff = affRow.$update({ Id: affRow.Id });
    else
        aff = affRow.$save({ Id: affRow.Id });
    return aff;
};

当他们被阅读时(以防他们已经搞砸了):

var setAttendanceGetSInfo = function (CourseId, PID) {
    return setAttendanceInfo(CourseId, PID)
    .then(function (result) {
        return $q.all([
            $http.get("../api/Axtra/getSInfo/" + model.event.Id),
            $http.get("../api/Axtra/GetStartAndEndDateTime/" + aRow.Rid)
        ]);
    }).then(function (result) {
        var r = result.data;
        var e = Date.fromISO(r.Start);
        var f = Date.fromISO(r.End);
        angular.extend(model.event, {
            examDate: moment(e).format("MM/DD/YYYY"),
            examStartTime: moment(e).format("MM/DD/YYYY hh:mm A"),
            examEndTime: moment(f).format("MM/DD/YYYY hh:mm A")
        });
        return result.sInfo;
    });
};