【问题标题】:Renaming JSON properties if they contain a certain character without JSON.stringify如果 JSON 属性包含某个没有 JSON.stringify 的字符,则重命名它们
【发布时间】:2017-08-10 19:49:20
【问题描述】:

我有一个独特的问题。我目前正在尝试将 JSON 数据源连接到剑道网格。正因为如此,在 JSON 中的任何地方都不能有 #,因为它会与 kendo 混淆。所以我必须采取这样的数据:

[
    {"ID#": "1", "Prop1": "Val1#"},
    {"ID#": "2", "Prop2": "Val2"},
]

并转义#,以便剑道能够理解:

[
    {"ID\#": "1", "Prop1": "Val1\#"},
    {"ID\#": "2", "Prop2": "Val2"},
]

最大的问题是 JSON 几乎可以与任何东西相似:可能有任意数量/名称的键/值。

我的尝试:

我试图像这样逃避#var dataSource = JSON.parse(result.replace("#", "\\#")); 但是,当我尝试这个时,JSON.parse 会抛出一个错误:

SyntaxError: JSON.parse: bad escaped character at line 1 column 7 of the JSON data

然后我尝试将# 替换为#。事实证明,Kendo 只能支持行中的 HTML 实体,而不支持列标题中的 HTML 实体,而不会出现模板错误。所以我可以像这样替换属性值:

var dataSource = JSON.parse(result, function(key, value) {
       if(typeof value === "string") {
           return value.replace("#", "#");
       }
       else {
           return value;
       }
 });

这适用于价值观!但是,这些键仍然可能包含#,这会弄乱我的剑道网格。我试图遍历每个对象和键/对,如果它有#,则替换键,但由于某种原因,当我调用Object.keys 时,返回的数组只是 0 和 1,即使这不是我的数据已命名。

for (var object in dataSource) {
     for (var property in object) {
          if (object.hasOwnProperty(property)) {
                var keys = Object.keys(object);
                for(var key in keys) {
                     var oldName = key;
                     var newName = key.replace("#", "\#");
                     object[newName] = object[oldName];       
                     delete object[oldName];           
                 }   
           }
      }
 }

上面的这部分似乎没有效果。它甚至不会抛出错误。

我还尝试将# 替换为字符串:hashliteral。然后,在创建剑道网格后,我尝试使用 jQuery 将所有 hashliteral 替换为 #

var fixed = $("#grid").html().replace(/hashliteral/g, "#");
$("#grid").html(fixed);

这确实有效,但它破坏了剑道网格和所有绑定。网格功能是必须的,所以我不能使用这个解决方案。

回顾一下

我正在尝试删除/替换或转义 JSON 数据中的所有 #,以便它与我的 Kendo Grid 一起正常工作。

  • 我不能使用JSON.stringify 并将# 替换为\\#,因为那样JSON.parse 会失败。
  • 我不能使用#,因为 Kendo 标头不能有特殊字符。
  • 我无法使用 jQuery 修改 $("#grid").html(),因为它破坏了网格绑定。
  • 密钥可以是任何东西。该值也可以是任何值。
  • JSON 不是嵌套的或复杂的。
  • 我无法在 KendoGrid 列上定义字段/标题,因为我不知道字段/标题需要是什么,数据非常动态。

我准备放弃这一点,只需从数据中删除所有#。如果有人能想到某种方法来实现这一点:重命名对象的属性,以便所有# 前面都有\,将不胜感激。在我的一生中,我找不到解决这个问题的办法。

【问题讨论】:

  • 在值中包含# 似乎完全没有问题。检查this out。虽然我设法用# 逃脱了标题的标题,但它搞砸了模板。 IMO 这是一个错误,无论如何它都应该处理它......
  • 为什么不循环遍历所有属性并构建一个新对象以进行进一步处理?我错过了什么吗?
  • @lexith 在不知道旧键/新键是什么的情况下,我还没有找到一种方法来做到这一点

标签: javascript jquery json kendo-ui kendo-grid


【解决方案1】:

我认为您已经走在正确的轨道上,但是创建一个新的对象列表会更容易:

var newObjects = [];

for (var i = 0; i < dataSource.length; i++ ) {
    var currentObject = dataSource[i];
    var newObject = {};

    for (var key in currentObject) {
        if (currentObject.hasOwnProperty(key)) {
             var newKeyName = key.replace("#", "__HASHLITERAL__");
             var newValue = currentObject[key];
             if(typeof newValue === "string") {
                  newValue = newValue.replace("#", "__HASHLITERAL__");
             }
             newObject[newKeyName] = newValue;
        }
    }

    newObjects.push(newObject);
}

console.log(newObjects);

希望对您有所帮助,我正确理解了您的问题。


编辑:您不能使用像 \ 这样的特殊字符作为键,因此您必须实际使用像 ___something___ 这样的独特字符,然后您可以将其替换为以后的任何字符。

【讨论】:

  • 谢谢!这正是我一直在寻找的,你说得对,我已经到了一半。创建网格后,我只是做了一个 jQuery 查找并将__HASHLITERAL__ 替换为#。现在效果很好。
  • 乐于助人:)
猜你喜欢
  • 2021-09-07
  • 1970-01-01
  • 1970-01-01
  • 2011-03-14
  • 1970-01-01
  • 2014-03-22
  • 1970-01-01
  • 2011-01-22
  • 2021-10-23
相关资源
最近更新 更多