2013-11-28 3 views
11

Hallo Ich habe einen kleinen Winkel App wie so:Winkeltypeerror: Konvertieren Kreisstruktur zu JSON

// 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(){ 
     ... 
    } 
}); 

Das Problem ist, mit einer Aufgabe zu aktualisieren und das übergeordneten Projekt verlassen, wie ist. Wenn ich das Elternprojekt ändere, funktioniert alles gut. Wenn ich dasselbe Elternprojekt verwende, dann erhalte ich:

Ich bin mir nicht ganz sicher, was hier passiert. Jede Hilfe würde sehr geschätzt werden.

EDIT

Also, ich kann das Problem wie folgt lösen:

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

Dies funktioniert, wie ich die task.project.id nur wirklich brauchen, um das Objekt zu aktualisieren. I denke, das Problem ist aufgrund dieser Tatsache, dass die Aufgabe verweist auf ein Elternprojekt, das wiederum auf die Kind Aufgaben usw. Ich bin mir nicht ganz sicher über diese hart.

Allerdings scheint diese Lösung ein wenig hacky zu mir und ich würde gerne eine bessere Lösung sehen.

Antwort

14

Irgendwo Sie versuchen, ein Objekt zu JSON zu konvertieren, und das hat einen zirkulären Verweis darin, so etwas wie dies bedeuten:

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

nun versuchen, dies zu JSON konvertieren wird fehlschlagen, und produzieren Ihre Fehler .

am bearbeiteten Post Sehen, ist Ihre Datenstruktur etwas wie folgt aus:

task.parent -> {project} 

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

Dies soll die Beziehung modellieren „Projekt hat mehrere Aufgaben“ und „Task gehört zu einem Projekt“.

Nun kann dies offensichtlich nicht mehr in das json-Format konvertiert werden, aufgrund der Zirkelreferenzierung.

Für die Datenstruktur, warum nicht mit:

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

task = { "id": 123, 
     "idproject": 42, 
      ... 
     } 

Jedes Mal, wenn Sie die Beziehungen in Ihrer AngularJS App zeigen haben, können Sie mit Filtern gehen könnte. Wenn Sie zeigen möchten, was zu einem Projekt gehört, filtern Sie alle Aufgaben nach projectid.

Oder rufen Sie nur die erforderlichen Daten von Ihrem Back-End im laufenden Betrieb ab, indem Sie angeben, welche Aufgaben das Back-End für eine bestimmte Projekt-ID hat.

Das ist eine Möglichkeit, es zu tun. Natürlich würde es genauso gut funktionieren, wenn das Backend geeignete Aktualisierungsanforderungen akzeptiert, z. Das Aktualisieren eines Projekts würde die Projekt-ID und ein Array von Aufgaben-IDs erfordern.

+0

hmmm. Nun, ich benutze JSON.stringify nicht in meinem Code. Es scheint bei der Methode "ConcernService.update" fehlzuschlagen. –

+0

Das Interessante ist, dass alles funktioniert, wenn ich das Projekt im Auswahlfeld ändere. Ich weiß also, es gibt einen Zirkelverweis auf 'new_task.project', aber ich bin mir nicht sicher, wo es ist. –

+0

Wenn Sie Chrome Browser haben, können Sie die Entwickler-Tools verwenden, um das Javascript zu debuggen, das gleiche funktioniert mit Firebug Addon in Mozilla.Sie können das Objekt während der Ausführung in Ihrem Code überprüfen und es mit dem Arbeitsfall mit dem Problemfall vergleichen. – bgse