将Observable Array转换为嵌套的JSON

时间:2015-07-21 20:41:24

标签: javascript jquery arrays json knockout.js

我在将一组信息正确存储为JSON时遇到问题。

我做了fiddle to illustrate the problem。输入一组标签,然后查看控制台以查看输出。

更多解释:

所以我有一个输入,它带有逗号分隔的标签列表,然后我会格式化。

function createTagArray() {
   // given an input value of 'tag1, tag2, tag3'
   // returns array = ['tag1', 'tag2', 'tag3']
} 

我认为我接下来需要做的是以下内容: 循环遍历数组并创建一个标记'每个项目的对象,其中还包括标记的ID和与标记关联的联系人的ID。

每个对象都被推送到tags,一个可观察的数组。

function single_tag(id, contactId, tagLabel) {
    var self = this;

    self.id = id;
    self.contactId = contactId;
    self.tagLabel = tagLabel;
}

function createTags() {
  var array = createTagArray();

  for (var i = 0; i < array.length; i++) {
    self.tags().push(new single_tag(uuid.generate(), self.contactId, array[i]));
  }
}

然后,我将其转换为JSON

self.contactInformation = function() {
  return ko.toJS({
    "id": self.contactId,
    "firstname": self.firstname(),
    "lastname": self.lastname(),
    ... other fields ...
    "tags": self.tags(),
  })
}

但是,当我检查调用此函数的控制台输出时,tags是一个数组的集合,而不是一个很好的json对象。

Messed up tags JSON

如何正确格式化?

我尝试了this suggestion,标签json的结构正确,但它存储了转义引号,所以看起来不对。

感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

我会向你推荐kout的knockout.mapping插件,它允许地图复杂的JSON结构来查看模型,即使没有声明。

来自documentation

  

假设您有一个如下所示的JavaScript对象:

var data = {
    name: 'Scot',
    children: [
        { id : 1, name : 'Alicw' }
    ]
}
  

您可以毫无问题地将其映射到视图模型:

var viewModel = ko.mapping.fromJS(data);
  

现在,让我们说数据更新为没有任何拼写错误:

var data = {
    name: 'Scott',
    children: [
        { id : 1, name : 'Alice' }
    ]
}
  

这里发生了两件事:名称从 Scot 更改为 Scott ,而 children [0] .name 已从更改Alicw 到没有错字的 Alice 。您可以根据以下新数据更新viewModel:

ko.mapping.fromJS(data, viewModel);
  

名称会按预期更改。但是,在children数组中,子项(Alicw)将被完全删除并添加一个新的(Alice)。这并不完全是你所期望的。相反,你原本以为只有孩子的name属性从Alicw更新为Alice,而不是更换了整个孩子!

     

...

     

要解决此问题,您可以指定映射插件应使用哪个键来确定对象是新对象还是旧对象。你可以这样设置:

var mapping = {
    'children': {
        key: function(data) {
            return ko.utils.unwrapObservable(data.id);
        }
    }
}
var viewModel = ko.mapping.fromJS(data, mapping);

答案 1 :(得分:0)

在jsfiddle中你使用的是Knockout 3.0,它不支持textInput。这是在3.2中添加的。要使用版本3.2,您需要使用如下的cdn:http://cdnjs.com/libraries/knockout

你的绑定中有typeo。 sumbit应为submit

single_tag的构造函数出现问题。我没有使用id,所以我删除了它:

function single_tag(contactId, tagLabel) {
    var self = this;

    self.contactId = contactId;
    self.tagLabel = tagLabel;
}

目前还没有设置contactId,因为observable尚未设置为值。

要转换为JSON,您需要使用ko.toJSON代替ko.toJS

self.contactInformation = function() {
    return ko.toJSON({
      "firstname": self.firstname(),
      "tags": self.tags(),
    })
}

现在当控制台写出数组时出现:

{
  "firstname":"test",
  "tags":[
    {"tagLabel":"test1"},
    {"tagLabel":"test2"},
    {"tagLabel":"test3"}
  ]
}

JsFiddle

答案 2 :(得分:0)

所以我的问题比我意识到的更基本。我正在使用JSON Server来提供我的数据,我从数据库的两个部分(联系人和标签)中提取信息。

当我尝试更新我的标签时,我试图将它们应用于我的数据库中联系人JSON上不存在的属性。然而,分别发布标签。