2013-08-19 102 views
0

我有一个JavaScript对象,我用JSON.stringify字符串化,返回一个JSON字符串与父数据和子数据。JSON.parse返回空值的儿童对象,儿童值不被解析

当我尝试将此字符串解析回对象时,子对象现在为空。

function cacheForm(agency) { 

var agency = ko.toJS(this); //easy way to get a clean copy 
delete agency.contacts; //remove an extra property 

     for (i in agency.offices) { 
      for (val in agency.offices[i]) { 
       //delete agency.offices[i].agency; 
       //delete agency.offices[i].agencyID; 
      } 
     } 

      for (i in agency.offices) { 
       for (ii in agency.offices[i].contacts) { 
        for (val in agency.offices[i].contacts[ii]) { 
         //delete agency.offices[i].contacts[ii].office; 
         //delete agency.offices[i].contacts[ii].agencyID; 
         //delete agency.offices[i].contacts[ii].officeID; 
        } 
       } 
      } 

       var value = agency; 

       var cache = []; 
       parsed = JSON.stringify(value, function (key, value) { 
        if (typeof value === 'object' && value !== null) { 
         if (cache.indexOf(value) !== -1) { 
          // Circular reference found, discard key 
          return; 
         } 
         // Store value in our collection 
         cache.push(value); 
        } 

        return value; 
       }); 


       var data = JSON.parse(parsed); 
    } 

编辑我的视图模型的

机构的一部分,我路过到我cacheForm功能,我使用

var agency = ko.toJS(this); 

有一个对象,可以提供我的数据解析为JSON字符串。我可能在我的文章中删除了这段代码,因为我的原始代码有很多注释。

My agency object before stringify - it has child data

+0

看到实际的JSON将帮助我们,如果可能的话u能张贴链接到它? – Vishwanath

+0

使用http://fpaste.org或使用粘贴bin粘贴你的json –

+0

是的,给我们实际的数据。无论如何,我的赌注是“注意:你不能使用replacer函数从数组中删除值,如果你返回未定义的或函数,那么使用null。” ([MDN](https://developer.mozilla.org/en-US/docs/Using_native_JSON#The_replacer_parameter)) – nmaier

回答

0

所以我最终解决了我的问题,这就是我做到的。

​​

首先,我将ko.observableArray传递给函数cacheForm。这个参数被称为代理,它是我的viewmodel的一部分。

我想解析我的observableArray并将其转换为标准的javascript对象。通过使用ko.toJS我可以做到这一点。使用toJS后将没有ko构造函数。

然后我得到我的JSON字符串。由于我的对象有子女和孙子女,我必须分别解析这些部分。 Stringify不喜欢对象内的数组,它们将更改为null,并且您的子数据将丢失。

因为圆形递归的,我必须使用此:

var s = YUI().use("json-stringify", function (Y) { 

这是雅虎API的一部分。这是脚本参考:

<script src="http://yui.yahooapis.com/3.11.0/build/yui/yui-min.js"></script> 

Y.JSON.stringify接受一个对象作为一个参数和选项paremter这是一个数组。这个数组的目的是包含你想要对象化的对象的属性名称。从其他论坛我发现这被称为白名单。

使用我所有的JSON字符串,我可以将它们存储在HTML5本地存储中。

当页面加载时,然后检查我的本地存储是否包含数据。如果为true,则检索我的数据并从JSON字符串序列化为JavaScript对象。

define(['services/datacontext'], function (dataContext) { 
    var initialized = false; 
    var agency; 

    if (localStorage.Agency && localStorage.Offices && localStorage.Contacts) { 
     var objAgency = new Object(ko.mapping.fromJSON(localStorage.getItem('Agency'))); 
     var objOffices = new Object(ko.mapping.fromJSON(localStorage.getItem('Offices'))); 
     var objContacts = new Object(ko.mapping.fromJSON(localStorage.getItem('Contacts'))); 

     objAgency.offices = objOffices; 
     objAgency.offices._latestValue[0].contacts = objContacts; 


     agency = ko.observableArray([ko.mapping.fromJS(objAgency)]); 
     ko.applyBindings(agency); 

     initialized = true; 

    } 
    else { 
     agency = ko.observableArray([]); 
    } 

最后我重建我的对象是怎么回事之前字符串化并将其映射回一个observableArray最后绑定。

希望这可以帮助其他人使用knockoutJS和复杂对象的组合。

请参阅以下我全码:

define(['services/datacontext'], function (dataContext) { 
    var initialized = false; 
    var agency; 

    if (localStorage.Agency && localStorage.Offices && localStorage.Contacts) { 
     var objAgency = new Object(ko.mapping.fromJSON(localStorage.getItem('Agency'))); 
     var objOffices = new Object(ko.mapping.fromJSON(localStorage.getItem('Offices'))); 
     var objContacts = new Object(ko.mapping.fromJSON(localStorage.getItem('Contacts'))); 

     objAgency.offices = objOffices; 
     objAgency.offices._latestValue[0].contacts = objContacts; 


     agency = ko.observableArray([ko.mapping.fromJS(objAgency)]); 
     ko.applyBindings(agency); 

     initialized = true; 

    } 
    else { 
     agency = ko.observableArray([]); 
    } 


    var save = function (agency, myStoredValue) { 
     // Clear Cache because user submitted the form. We don't have to hold onto data anymore. 
     //amplify.store("Agency", null); 
     return dataContext.saveChanges(agency); 
    }; 

    var vm = { // This is my view model, my functions are bound to it. 
     //These are wired up to my agency view 
     activate: activate, 
     agency: agency, 
     title: 'agency', 
     refresh: refresh, // call refresh function which calls get Agencies 
     save: save, 
     cacheForm: cacheForm 
    }; 
    return vm; 

    function activate() { 

     vm.agency; 

     if (initialized) { 
      return; 
     } 

     initialized = false; 

     return refresh(); 

    } 

    function refresh() { 
     return dataContext.getAgency(agency); 
    } 


    function cacheForm(agency) { 
     // GET my object from agency vm 
     var agency = ko.toJS(agency); 

     var s = YUI().use("json-stringify", function (Y) { 

      var jsonStrAgency = Y.JSON.stringify(agency, ["activities", "agencyName", "agencyID", "campaignBillings", "category", "declaredBillings", "immediateParent", "numberOfEmployees", "ultimateParent", "uRL"]); // Use an array of acceptable object key names as a whitelist. 
      var jsonStrOffices, jsonStrContacts; 

      for (i in agency.offices) { 
       jsonStrOffices = Y.JSON.stringify(agency.offices, ["address1", "address2", "address3", "address4", "address5", "agencyID", "faxNumber", "officeID", "postCode", "telephoneNumber"]); 

       for (ii in agency.offices[i].contacts) { 
        jsonStrContacts = Y.JSON.stringify(agency.offices[i].contacts, ["agencyID", "emailAddress", "firstName", "jobName", "officeID", "personID", "surName", "title"]); 
       } 
      } 

      localStorage.setItem('Agency', jsonStrAgency); 
      localStorage.setItem('Offices', jsonStrOffices); 
      localStorage.setItem('Contacts', jsonStrContacts); 
     }); 
    } 
}); 
3

您的问题最初显示了一个屏幕截图,其中突出显示了data.offices = [null]

这不是解析错误,而是stringify中的错误。你的贴已经有data.offices = [null]。关于replacer

MDN状态:

注意:您不能使用替代品功能从数组中删除值。如果您返回未定义或函数,则使用null。

并且此外关于stringify

如果未定义,函数,或一个XML值转换期间遇到它要么省略(当它在一个对象被发现)或截尾为null时(当它在数组中找到)。

我没有访问原始的对象,因此不能告诉你们两个都打...

实施toJSON(或只是明确地构建从源对象的另一个对象),而不是replacer过滤阵列将是要走的路,如果问题是在您的当前replacer实施。

+0

我不确定我会提供什么来筛选数组。你有一个例子吗? –

+0

该文档声明:你不能提供任何东西给'stringify'来过滤数组。你可以构造一个已经过滤的对象,并将其提供给'stringify',或者通过在你的对象上实现'toJSON'来隐式地执行,或者明确地像'JSON.stringify(doFilterMyObject(obj))'。 – nmaier