javascript - 从字符串解析 JSON

标签 javascript json

fiddle :https://mikethedj4.github.io/kodeWeave/editor/#6aade2727e9d2a1a20eea1e948fe7dbc

我在从字符串中解析 JSON 时遇到了一点困难。在我的应用中,我在 onclick 事件中抓取它

var data = {
  "files": JSON.parse($(selector).nextAll('textarea').val())
};

并将数据存储到这样的文本区域中......

JSON.stringify(data)

为了使调试过程更容易,我只使用了一个简单的字符串,因为它在下面的代码中进行了替换。

在控制台中,它显示为...

Uncaught TypeError: Cannot read property 'content' of undefined

我从 var jsonSets = data.files["settings.json"].content; 中删除了内容,我能够越过它,但得到...

Uncaught TypeError: Cannot read property 'siteTitle' of undefined

我打算用 .content 来抓取。我不确定为什么会出现此错误,甚至不确定如何克服它。

谁能解释我做错了什么?

如何获取我的 settings.jsonsiteTitle 值的字符串?

var files = {
  "files": {
    "index.html": {
      "content": "<div ng-app=\"App\" ng-controller=\"AppCtrl\" layout=\"row\" layout-fill ng-cloak>\n  <md-sidenav class=\"md-sidenav-left md-whiteframe-z2\" role=\"sidenav\" md-component-id=\"left\" md-is-locked-open=\"$mdMedia('gt-md')\">\n    <md-toolbar class=\"md-tall md-hue-2\" layout-align=\"end end\">\n      <div class=\"md-toolbar-tools\" layout layout-padding>\n        <md-icon>{{data.user.icon}}</md-icon>\n        <div layout=\"column\" layout-padding>\n          <span class=\"md-body-2\">{{data.user.name}}</span>\n          <span class=\"md-caption\">{{data.user.email}}</span>\n        </div>\n        <span flex></span>\n        <md-button class=\"md-icon-button\" aria-label=\"User Settings\" ng-click=\"toast('Logout')\">\n          <md-icon>more_vert</md-icon>\n        </md-button>\n      </div>\n    </md-toolbar>\n    <md-content role=\"navigation\">\n      <md-list ng-repeat=\"section in data.sidenav.sections\">\n        <md-list-item ng-click=\"section.expand = !section.expand\">\n          <p class=\"md-subheader md-primary\">{{section.name}}</p>\n          <span flex></span>\n          <md-icon class=\"md-primary md-icon-button\">{{section.expand ? 'arrow_drop_up' : 'arrow_drop_down'}}</md-icon>\n        </md-list-item>\n        <md-list-item ng-show=\"section.expand\" ng-repeat=\"action in section.actions\" ng-click=\"toast(action.link)\">\n          <md-icon>{{action.icon}}</md-icon>\n          <p class=\"md-body-2\">{{action.name}}</p>\n          <span flex></span>\n          <md-icon>chevron_right</md-icon>\n        </md-list-item>\n    </md-content>\n  </md-sidenav>\n  <section layout=\"column\" role=\"main\" flex>\n    <md-toolbar role=\"toolbar\">\n      <div class=\"md-toolbar-tools\">\n        <md-button class=\"md-icon-button\" ng-click=\"toggleSidenav('left')\" hide-gt-md aria-label=\"Menu\">\n          <md-icon>menu</md-icon>\n        </md-button>\n        <h4 class=\"md-title\">{{data.title}}</h4>\n        <span flex></span>\n        <md-button class=\"md-icon-button\" ng-repeat=\"button in data.toolbar.buttons\" aria-label={{button.name}} ng-click=\"toast(button.link)\">\n          <md-icon>{{button.icon}}</md-icon>\n        </md-button>\n        <md-menu md-position-mode=\"target-right target\" ng-repeat=\"menu in data.toolbar.menus\">\n          <md-button class=\"md-icon-button\" aria-label=\"{{menu.name}}\" ng-click=\"$mdOpenMenu($event)\">\n            <md-icon>{{menu.icon}}</md-icon>\n          </md-button>\n          <md-menu-content width={{menu.width}}>\n            <md-subheader>{{menu.name}}</md-subheader>\n            <md-menu-item ng-repeat=\"action in menu.actions\">\n              <md-button layout-fill md-ink-ripple ng-click=\"toast(action.message)\">\n                <md-icon md-class=\"{{action.error ? 'md-warn' : 'md-primary'}}\" md-menu-align-target>{{action.completed ? 'done' : 'hourglass_empty'}}</md-icon>\n                {{action.name}}\n              </md-button>\n            </md-menu-item>\n          </md-menu-content>\n        </md-menu>\n      </div>\n    </md-toolbar>\n    <section id=\"content\" role=\"content\" layout=\"column\" layout-padding md-scroll-y>\n      <md-content class=\"md-whiteframe-z2\" ng-cloak>\n        <md-list ng-repeat=\"list in data.content.lists\">\n          <div class=\"md-actions\" layout layout-align=\"end center\">\n            <md-subheader class=\"md-no-sticky md-primary\">{{list.name}}</md-subheader>\n            <span flex></span>\n            <md-menu md-position-mode=\"target-right target\">\n              <md-button class=\"md-icon-button\" aria-label=\"{{list.menu.name}}\" ng-click=\"$mdOpenMenu($event)\">\n                <md-icon class=\"md-primary\">settings</md-icon>\n              </md-button>\n              <md-menu-content width={{list.menu.width}}>\n                <md-subheader>{{list.menu.name}}</md-subheader>\n                <md-menu-item ng-repeat=\"action in list.menu.actions\">\n                  <md-button layout-fill md-ink-ripple ng-click=\"toastList(action.message)\">\n                    <md-icon md-class=\"{{action.error ? 'md-warn' : 'md-primary'}}\" md-menu-align-target>{{action.completed ? 'done' : 'hourglass_empty'}}</md-icon>\n                    {{action.name}}\n                  </md-button>\n                </md-menu-item>\n              </md-menu-content>\n            </md-menu>\n          </div>\n          <md-divider></md-divider>\n          <md-list-item class=\"md-2-line\" ng-repeat=\"item in list.items\">\n            <md-checkbox ng-click=\"toggle(item, selected)\"></md-checkbox>\n            <md-content class=\"md-list-item-text\" layout=\"column\">\n              <h3 class=\"md-body-2\">{{item.name}}</h3>\n              <p class=\"md-caption\">{{item.description}}</p>\n            </md-content>\n            <span flex></span>\n            <md-icon aria-label=\"Show Item\" ng-click=\"toast(item.link)\">chevron_right</md-icon>\n          </md-list-item>\n        </md-list>\n      </md-content>\n    </section>\n  </section>\n</div>"
    }
    , "index.css": {
      "content": "body {\n  overflow: hidden;\n  background-color: #EEEEEE;\n}\n\nmd-whiteframe {\n  background: #fff;\n}\n\n#content {\n  padding: 24px;\n}\n\n"
    }
    , "index.js": {
      "content": "angular.module('App', [\n  'ngMaterial'\n]);\n\nangular.module('App').config(function($mdThemingProvider) {\n  $mdThemingProvider.theme('default').primaryPalette('indigo');\n})\n\nangular.module('App').controller('AppCtrl', function($scope, $mdSidenav, $mdToast) {\n  $scope.toggleSidenav = function(menu) {\n    $mdSidenav(menu).toggle();\n  }\n  $scope.toast = function(message) {\n    var toast = $mdToast.simple().content('You clicked ' + message).position('bottom right');\n    $mdToast.show(toast);\n  };\n  $scope.toastList = function(message) {\n    var toast = $mdToast.simple().content('You clicked ' + message + ' having selected ' + $scope.selected.length + ' item(s)').position('bottom right');\n    $mdToast.show(toast);\n  };\n  $scope.selected = [];\n  $scope.toggle = function(item, list) {\n    var idx = list.indexOf(item);\n    if (idx > -1) list.splice(idx, 1);\n    else list.push(item);\n  };\n  $scope.data = {\n    title: 'Dashboard',\n    user: {\n      name: 'Angular Ninja',\n      email: 'angular@ninja.com',\n      icon: 'face'\n    },\n    toolbar: {\n      buttons: [{\n        name: 'Button 1',\n        icon: 'add',\n        link: 'Button 1'\n      }],\n      menus: [{\n        name: 'Menu 1',\n        icon: 'message',\n        width: '4',\n        actions: [{\n          name: 'Action 1',\n          message: 'Action 1',\n          completed: true,\n          error: true\n        }, {\n          name: 'Action 2',\n          message: 'Action 2',\n          completed: false,\n          error: false\n        }, {\n          name: 'Action 3',\n          message: 'Action 3',\n          completed: true,\n          error: true\n        }]\n      }]\n    },\n    sidenav: {\n      sections: [{\n        name: 'Section 1',\n        expand: true,\n        actions: [{\n          name: 'Action 1',\n          icon: 'settings',\n          link: 'Action 1'\n        }, {\n          name: 'Action 2',\n          icon: 'settings',\n          link: 'Action 2'\n        }]\n      }, {\n        name: 'Section 2',\n        expand: false,\n        actions: [{\n          name: 'Action 3',\n          icon: 'settings',\n          link: 'Action 3'\n        }]\n      }, {\n        name: 'Section 3',\n        expand: false,\n        actions: [{\n          name: 'Action 4',\n          icon: 'settings',\n          link: 'Action 4'\n        }, {\n          name: 'Action 5',\n          icon: 'settings',\n          link: 'Action 5'\n        }, {\n          name: 'Action 6',\n          icon: 'settings',\n          link: 'Action 6'\n        }]\n      }]\n    },\n    content: {\n      lists: [{\n        name: 'List 1',\n        menu: {\n          name: 'Menu 1',\n          icon: 'settings',\n          width: '4',\n          actions: [{\n            name: 'Action 1',\n            message: 'Action 1',\n            completed: true,\n            error: true\n          }]\n        },\n        items: [{\n          name: 'Item 1',\n          description: 'Description 1',\n          link: 'Item 1'\n        }, {\n          name: 'Item 2',\n          description: 'Description 2',\n          link: 'Item 2'\n        }, {\n          name: 'Item 3',\n          description: 'Description 3',\n          link: 'Item 3'\n        }]\n      }]\n    }\n  }\n});"
    }
    , "libraries.json": {
      "content": "{\"alertify\":false,\"angular\":false,\"angularmaterial\":false,\"animatecss\":false,\"backbone\":false,\"bootstrap\":false,\"chartjs\":false,\"codemirror\":false,\"createjs\":false,\"d3\":false,\"dojo\":false,\"enhance\":false,\"fabricjs\":false,\"foundation\":false,\"handlebars\":false,\"hintcss\":false,\"immutable\":false,\"jarallax\":false,\"jquery\":false,\"jqueryui\":false,\"jquerytools\":false,\"jqxsplitter\":false,\"jszip\":false,\"kinetic\":false,\"knockout\":false,\"lodash\":false,\"mdl\":false,\"modernizer\":false,\"moment\":false,\"momenttimezone\":false,\"mootools\":false,\"normalize\":false,\"paperjs\":false,\"polyui\":false,\"prefixfree\":false,\"processingjs\":false,\"prototypejs\":false,\"qooxdoo\":false,\"react\":false,\"raphael\":false,\"requirejs\":false,\"showdown\":false,\"scriptaculous\":false,\"smoothscroll\":false,\"snapsvg\":false,\"svgjs\":false,\"threejs\":false,\"uikit\":false,\"underscorejs\":false,\"vue\":false,\"webfontloader\":false,\"yui\":false,\"zepto\":false}"
    }
    , "settings.json": {
      "content": "{\"siteTitle\":\"Angular Material\",\"WeaveVersion\":\"0.1\",\"editorFontSize\":\"14\",\"description\":\"Angular Material Test\",\"author\":\"Someone\"}"
    }
  }
}
var data = {
  "files": files
};
var jsonSets = data.files["settings.json"].content;

console.log(jsonSets.siteTitle);

最佳答案

缺少一个属性(files),您需要解析 JSON 值以将其转换为对象:

var files = {
  "files": {
    "index.html": {
      "content": "<div ng-app=\"App\" ng-controller=\"AppCtrl\" layout=\"row\" layout-fill ng-cloak>\n  <md-sidenav class=\"md-sidenav-left md-whiteframe-z2\" role=\"sidenav\" md-component-id=\"left\" md-is-locked-open=\"$mdMedia('gt-md')\">\n    <md-toolbar class=\"md-tall md-hue-2\" layout-align=\"end end\">\n      <div class=\"md-toolbar-tools\" layout layout-padding>\n        <md-icon>{{data.user.icon}}</md-icon>\n        <div layout=\"column\" layout-padding>\n          <span class=\"md-body-2\">{{data.user.name}}</span>\n          <span class=\"md-caption\">{{data.user.email}}</span>\n        </div>\n        <span flex></span>\n        <md-button class=\"md-icon-button\" aria-label=\"User Settings\" ng-click=\"toast('Logout')\">\n          <md-icon>more_vert</md-icon>\n        </md-button>\n      </div>\n    </md-toolbar>\n    <md-content role=\"navigation\">\n      <md-list ng-repeat=\"section in data.sidenav.sections\">\n        <md-list-item ng-click=\"section.expand = !section.expand\">\n          <p class=\"md-subheader md-primary\">{{section.name}}</p>\n          <span flex></span>\n          <md-icon class=\"md-primary md-icon-button\">{{section.expand ? 'arrow_drop_up' : 'arrow_drop_down'}}</md-icon>\n        </md-list-item>\n        <md-list-item ng-show=\"section.expand\" ng-repeat=\"action in section.actions\" ng-click=\"toast(action.link)\">\n          <md-icon>{{action.icon}}</md-icon>\n          <p class=\"md-body-2\">{{action.name}}</p>\n          <span flex></span>\n          <md-icon>chevron_right</md-icon>\n        </md-list-item>\n    </md-content>\n  </md-sidenav>\n  <section layout=\"column\" role=\"main\" flex>\n    <md-toolbar role=\"toolbar\">\n      <div class=\"md-toolbar-tools\">\n        <md-button class=\"md-icon-button\" ng-click=\"toggleSidenav('left')\" hide-gt-md aria-label=\"Menu\">\n          <md-icon>menu</md-icon>\n        </md-button>\n        <h4 class=\"md-title\">{{data.title}}</h4>\n        <span flex></span>\n        <md-button class=\"md-icon-button\" ng-repeat=\"button in data.toolbar.buttons\" aria-label={{button.name}} ng-click=\"toast(button.link)\">\n          <md-icon>{{button.icon}}</md-icon>\n        </md-button>\n        <md-menu md-position-mode=\"target-right target\" ng-repeat=\"menu in data.toolbar.menus\">\n          <md-button class=\"md-icon-button\" aria-label=\"{{menu.name}}\" ng-click=\"$mdOpenMenu($event)\">\n            <md-icon>{{menu.icon}}</md-icon>\n          </md-button>\n          <md-menu-content width={{menu.width}}>\n            <md-subheader>{{menu.name}}</md-subheader>\n            <md-menu-item ng-repeat=\"action in menu.actions\">\n              <md-button layout-fill md-ink-ripple ng-click=\"toast(action.message)\">\n                <md-icon md-class=\"{{action.error ? 'md-warn' : 'md-primary'}}\" md-menu-align-target>{{action.completed ? 'done' : 'hourglass_empty'}}</md-icon>\n                {{action.name}}\n              </md-button>\n            </md-menu-item>\n          </md-menu-content>\n        </md-menu>\n      </div>\n    </md-toolbar>\n    <section id=\"content\" role=\"content\" layout=\"column\" layout-padding md-scroll-y>\n      <md-content class=\"md-whiteframe-z2\" ng-cloak>\n        <md-list ng-repeat=\"list in data.content.lists\">\n          <div class=\"md-actions\" layout layout-align=\"end center\">\n            <md-subheader class=\"md-no-sticky md-primary\">{{list.name}}</md-subheader>\n            <span flex></span>\n            <md-menu md-position-mode=\"target-right target\">\n              <md-button class=\"md-icon-button\" aria-label=\"{{list.menu.name}}\" ng-click=\"$mdOpenMenu($event)\">\n                <md-icon class=\"md-primary\">settings</md-icon>\n              </md-button>\n              <md-menu-content width={{list.menu.width}}>\n                <md-subheader>{{list.menu.name}}</md-subheader>\n                <md-menu-item ng-repeat=\"action in list.menu.actions\">\n                  <md-button layout-fill md-ink-ripple ng-click=\"toastList(action.message)\">\n                    <md-icon md-class=\"{{action.error ? 'md-warn' : 'md-primary'}}\" md-menu-align-target>{{action.completed ? 'done' : 'hourglass_empty'}}</md-icon>\n                    {{action.name}}\n                  </md-button>\n                </md-menu-item>\n              </md-menu-content>\n            </md-menu>\n          </div>\n          <md-divider></md-divider>\n          <md-list-item class=\"md-2-line\" ng-repeat=\"item in list.items\">\n            <md-checkbox ng-click=\"toggle(item, selected)\"></md-checkbox>\n            <md-content class=\"md-list-item-text\" layout=\"column\">\n              <h3 class=\"md-body-2\">{{item.name}}</h3>\n              <p class=\"md-caption\">{{item.description}}</p>\n            </md-content>\n            <span flex></span>\n            <md-icon aria-label=\"Show Item\" ng-click=\"toast(item.link)\">chevron_right</md-icon>\n          </md-list-item>\n        </md-list>\n      </md-content>\n    </section>\n  </section>\n</div>"
    }
    , "index.css": {
      "content": "body {\n  overflow: hidden;\n  background-color: #EEEEEE;\n}\n\nmd-whiteframe {\n  background: #fff;\n}\n\n#content {\n  padding: 24px;\n}\n\n"
    }
    , "index.js": {
      "content": "angular.module('App', [\n  'ngMaterial'\n]);\n\nangular.module('App').config(function($mdThemingProvider) {\n  $mdThemingProvider.theme('default').primaryPalette('indigo');\n})\n\nangular.module('App').controller('AppCtrl', function($scope, $mdSidenav, $mdToast) {\n  $scope.toggleSidenav = function(menu) {\n    $mdSidenav(menu).toggle();\n  }\n  $scope.toast = function(message) {\n    var toast = $mdToast.simple().content('You clicked ' + message).position('bottom right');\n    $mdToast.show(toast);\n  };\n  $scope.toastList = function(message) {\n    var toast = $mdToast.simple().content('You clicked ' + message + ' having selected ' + $scope.selected.length + ' item(s)').position('bottom right');\n    $mdToast.show(toast);\n  };\n  $scope.selected = [];\n  $scope.toggle = function(item, list) {\n    var idx = list.indexOf(item);\n    if (idx > -1) list.splice(idx, 1);\n    else list.push(item);\n  };\n  $scope.data = {\n    title: 'Dashboard',\n    user: {\n      name: 'Angular Ninja',\n      email: 'angular@ninja.com',\n      icon: 'face'\n    },\n    toolbar: {\n      buttons: [{\n        name: 'Button 1',\n        icon: 'add',\n        link: 'Button 1'\n      }],\n      menus: [{\n        name: 'Menu 1',\n        icon: 'message',\n        width: '4',\n        actions: [{\n          name: 'Action 1',\n          message: 'Action 1',\n          completed: true,\n          error: true\n        }, {\n          name: 'Action 2',\n          message: 'Action 2',\n          completed: false,\n          error: false\n        }, {\n          name: 'Action 3',\n          message: 'Action 3',\n          completed: true,\n          error: true\n        }]\n      }]\n    },\n    sidenav: {\n      sections: [{\n        name: 'Section 1',\n        expand: true,\n        actions: [{\n          name: 'Action 1',\n          icon: 'settings',\n          link: 'Action 1'\n        }, {\n          name: 'Action 2',\n          icon: 'settings',\n          link: 'Action 2'\n        }]\n      }, {\n        name: 'Section 2',\n        expand: false,\n        actions: [{\n          name: 'Action 3',\n          icon: 'settings',\n          link: 'Action 3'\n        }]\n      }, {\n        name: 'Section 3',\n        expand: false,\n        actions: [{\n          name: 'Action 4',\n          icon: 'settings',\n          link: 'Action 4'\n        }, {\n          name: 'Action 5',\n          icon: 'settings',\n          link: 'Action 5'\n        }, {\n          name: 'Action 6',\n          icon: 'settings',\n          link: 'Action 6'\n        }]\n      }]\n    },\n    content: {\n      lists: [{\n        name: 'List 1',\n        menu: {\n          name: 'Menu 1',\n          icon: 'settings',\n          width: '4',\n          actions: [{\n            name: 'Action 1',\n            message: 'Action 1',\n            completed: true,\n            error: true\n          }]\n        },\n        items: [{\n          name: 'Item 1',\n          description: 'Description 1',\n          link: 'Item 1'\n        }, {\n          name: 'Item 2',\n          description: 'Description 2',\n          link: 'Item 2'\n        }, {\n          name: 'Item 3',\n          description: 'Description 3',\n          link: 'Item 3'\n        }]\n      }]\n    }\n  }\n});"
    }
    , "libraries.json": {
      "content": "{\"alertify\":false,\"angular\":false,\"angularmaterial\":false,\"animatecss\":false,\"backbone\":false,\"bootstrap\":false,\"chartjs\":false,\"codemirror\":false,\"createjs\":false,\"d3\":false,\"dojo\":false,\"enhance\":false,\"fabricjs\":false,\"foundation\":false,\"handlebars\":false,\"hintcss\":false,\"immutable\":false,\"jarallax\":false,\"jquery\":false,\"jqueryui\":false,\"jquerytools\":false,\"jqxsplitter\":false,\"jszip\":false,\"kinetic\":false,\"knockout\":false,\"lodash\":false,\"mdl\":false,\"modernizer\":false,\"moment\":false,\"momenttimezone\":false,\"mootools\":false,\"normalize\":false,\"paperjs\":false,\"polyui\":false,\"prefixfree\":false,\"processingjs\":false,\"prototypejs\":false,\"qooxdoo\":false,\"react\":false,\"raphael\":false,\"requirejs\":false,\"showdown\":false,\"scriptaculous\":false,\"smoothscroll\":false,\"snapsvg\":false,\"svgjs\":false,\"threejs\":false,\"uikit\":false,\"underscorejs\":false,\"vue\":false,\"webfontloader\":false,\"yui\":false,\"zepto\":false}"
    }
    , "settings.json": {
      "content": "{\"siteTitle\":\"Angular Material\",\"WeaveVersion\":\"0.1\",\"editorFontSize\":\"14\",\"description\":\"Angular Material Test\",\"author\":\"Someone\"}"
    }
  }
}
var data = {
  "files": files
};
var jsonSets = JSON.parse(data.files.files["settings.json"].content);

console.log(jsonSets.siteTitle);

你也可以直接使用 files 对象:

var jsonSets = JSON.parse(files.files["settings.json"].content);

关于javascript - 从字符串解析 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45270582/

相关文章:

javascript - 以编程方式滑回上一页

javascript - 在 jQuery 的匿名函数中将 HTML5 数据写入 JSON

javascript - 显示使用 PHP 和 MySQL 创建的 JSON 数据

javascript - 如何在 Javascript 中读取 JSON 文件并将其转换为对象

json - 如何在 Rust 中使用 reqwest 反序列化任意 json 结构?

java - 如何在 JSON 中存储键值对以在 Java 中反序列化?

javascript - 如何将数据库输出中的值添加到 Chart.js 折线图中的数据字段

javascript - 如何将 PHP 内容放入 iframe 中?

javascript - 如何根据 Javascript 中的动态范围确定值

JavaScript 执行