【问题标题】:angularJs TypeError: Converting circular structure to JSONangularJs TypeError:将循环结构转换为 JSON
【发布时间】:2013-11-28 22:11:17
【问题描述】:

我有一个像这样的小型 AngularJs 应用程序:

 // html

 <div ng-repeat="project in projects">
     <h3>{{ project.id }}</h3>
     <h3>{{ project.title }}</h3>
      <div ng-repeat="task in project.tasks">
          <h4>{{ task.id }}. {{ task.title }}</h4>
          <button class="btn btn-default" ng-click="showEditTask=true">Edit Task</button>
          <div class="box row animate-show-hide" ng-show="showEditTask">

              <h2>Create a New Task</h2>
              <form name="newTaskForm" class="form-horizontal">
                  Title: <br />
                  <input ng-model="new_task.title" type="text" id="title" name="title" class="form-control" placeholder="Title" required /><br />

                  Project: <br />
                  <select ng-model="new_task.project" ng-options="project.title for project in projects" class="form-control"></select><br>
              </form>

                  <button class="btn btn-success" ng-click="createTask(new_task)" ng-disabled="!newTaskForm.title.$valid">create</button>
          </div>
      </div>
 </div>


  // app.js

  concernsApp.factory('ConcernService', function ($http, $q) {

    ...

    update: function (obj_url, obj) {
        var defer = $q.defer();
        console.log(obj)
        $http({method: 'POST',
            url: api_url + obj_url + obj.id + '/',
            data: obj}).
            success(function (data, status, headers, config) {
                defer.resolve(data);
            }).error(function (data, status, headers, config) {
                defer.reject(status);
            });
        return defer.promise;
     },
   });


 concernsApp.controller('ProjectsCtrl', function ($scope, $http, ConcernService) {

    $scope.updateTask = function(obj) {
        ConcernService.update('tasks/', obj).then(function(){
        ...
    }
 });

问题在于更新任务并保持父项目不变。如果我更改父项目,一切正常。如果我使用相同的父项目,那么我会得到:

TypeError: Converting circular structure to JSON

我不完全确定这里发生了什么。

编辑

所以,我可以这样解决问题:

$scope.updateTask = function(obj) {
    parentProject = {'id': obj.project.id};
    obj.project = parentProject;
    ConcernService.update('tasks/', obj).then(function(){
        ...
    });
}; 

这很有效,因为我实际上只需要task.project.id 来更新对象。我认为问题是由于任务引用了父项目,而父项目又引用了子任务等。我对此并不完全确定。

但是,这个解决方案对我来说似乎有点 hacky,我希望看到更好的解决方案。

【问题讨论】:

    标签: json angularjs angularjs-scope


    【解决方案1】:

    您尝试将对象转换为 JSON 的地方,其中包含循环引用,意思是这样的:

    var myObj = new Object();
    myObject.reference = myObj;
    

    现在尝试将其转换为 JSON 将失败,并产生错误。

    查看您编辑的帖子,您的数据结构是这样的:

    task.parent -> {project}
    
    project.tasks -> [{task1},{task2},...]
    

    这应该建模关系“项目有多个任务”和“任务属于一个项目”。

    由于循环引用,现在这显然不能转换为 json 格式。

    对于数据结构,何乐而不为:

    project = { "id": 42,
                "tasks": [123, 124, 127, ... ],
              }
    
    task = { "id": 123,
             "idproject": 42,
                ...
           }
    

    当您必须在 angularjs 应用程序中显示关系时,您可以使用过滤器。如果要显示属于某个项目的内容,请按 projectid 过滤所有任务。

    或者通过请求后端针对特定项目 ID 执行的任务,即时从后端检索所需的数据。

    这是一种方法。当然,让后端接受适当的更新请求也可以正常工作,例如更新项目需要项目 ID 和任务 ID 数组。

    【讨论】:

    • 嗯。好吧,我没有在我的代码中使用 JSON.stringify。 ConcernService.update 方法似乎失败了。
    • 有趣的是,当我在选择字段中更改项目时,一切正常。所以我知道new_task.project 上有一个循环引用,但我不确定它在哪里。
    • 如果你有 Chrome 浏览器,你可以使用开发者工具来调试 javascript,同样适用于 Mozilla 中的 Firebug 插件。您可以在代码运行时检查该对象,并将其与工作案例与问题案例进行比较。
    • 这将是 $http 服务进行 json 转换,但这可能无济于事,因为它已经明显地出现了问题。
    • 请查看我的编辑以获取可行但看起来有点丑陋的解决方案:/
    猜你喜欢
    • 1970-01-01
    • 2018-10-05
    • 2016-01-22
    • 2017-06-29
    • 2019-01-05
    • 1970-01-01
    • 2023-01-31
    • 2016-12-13
    • 2020-08-18
    相关资源
    最近更新 更多