3

Ich habe eine Baumansicht, die Objekte mit verschachtelten Arrays enthält, die ich zu füllen versuche.ng-repeat innerhalb der Direktive wird nicht aktualisiert, wenn Objekte zur vorhandenen Sammlung hinzugefügt oder geändert werden

A working plunker may be found here.

Hier ist eine Aufschlüsselung, wie der Code strukturiert ist und was ich bisher ausprobiert.

In meiner treeview.html Ansicht lade ich die Treeview Direktive, die ich erstellt habe: Ich habe derzeit zwei, nur um die Bindungen zu testen. Der zweite Eintrag wird nicht gefüllt, bis das Kontrollkästchen "Vorfall" aktiviert wurde.

<H3>Tree View Sameple</H3> 

<div> 
    <h3>Treeview 1</h3> 
    <tree src="tree.treeData" iobj="object" filter="tree.getAggregateInfo(object, isSelected)"></tree> 
    <h3>Treeview 2 once object has been updated</h3> 
    <tree src="tree.treeData2" iobj="object" filter="tree.getAggregateInfo(object, isSelected)"></tree> 
</div> 
<hr/> 
<p>javascript object data</p> 
{{tree.treeData}} 

Die untere Bindung zeigt nur die Ausgabe der js-Datei. Wenn Sie in der Baumansicht auf das Kästchen Vorfall klicken, simuliere ich eine neue verschachtelte Sammlung, die als untergeordnetes Element unter dem Ereignisknoten der Struktur eingefügt wird.

Hier ist der Code in den treeviewController.js verwendet

(function() { 

    angular.module('app') 
      .controller('treeviewController', ['$log', '$scope', '$timeout', treeviewController]); 
    function treeviewController($log, $scope, $timeout) { 

     var vm = this; 
     //storage container for last node selected in tree 
     vm.lastNodeSelected = ''; 

     vm.treeData2 = {};//test container to reflect object once updated 
     //original data not an arry but an object holding an array 
     vm.treeData = 
      { 
       "children": [ 
        { 
         "name": "Document Type", 
         "children": [ 
         { 
          "name": "Incident", 
          "documentType": "Document Type", 
          "aggregateUponField": "_ocommon.documenttype", 
          "parent": "", 
          "count": 2950, 
          "children": null 
         }, 
         { 
          "name": "Some Event", 
          "documentType": "Document Type", 
          "aggregateUponField": "_ocommon.documenttype", 
          "parent": "", 
          "count": 2736, 
          "children": [{ 
             "name": "Some Event Date", 
             "children": [ 
                { 
                "name": "2008", 
                "documentType": "Incident Date", 
                "aggregateUponField": "dateincidentstart", 
                "parent": "", 
                "count": 451, 
                "children": null 
                }, 
                { 
                "name": "2009", 
                "documentType": "Incident Date", 
                "aggregateUponField": "dateincidentstart", 
                "parent": "", 
                "count": 407, 
                "children": null 
                }, 
                { 
                "name": "2010", 
                "documentType": "Incident Date", 
                "aggregateUponField": "dateincidentstart", 
                "parent": "", 
                "count": 426, 
                "children": null 
                } 
                ] 
             }] 
         } 
         ] 
        } 
       ] 
      }; 

     //aggregate data to be nested under incident 
     vm.newChildData = [ 
       { 
        "name": "Incident Date", 
        "children": [ 
        { 
         "name": "2008", 
         "documentType": "Incident Date", 
         "aggregateUponField": "dateincidentstart", 
         "parent": "", 
         "count": 451, 
         "children": null 
        }, 
        { 
         "name": "2009", 
         "documentType": "Incident Date", 
         "aggregateUponField": "dateincidentstart", 
         "parent": "", 
         "count": 407, 
         "children": null 
        }, 
        { 
         "name": "2010", 
         "documentType": "Incident Date", 
         "aggregateUponField": "dateincidentstart", 
         "parent": "", 
         "count": 426, 
         "children": null 
        } 
        ] 
       } 

     ]; 


     var loadData = function() { 
      //stip out array 
      var children = vm.treeData.children; 
      //search array for matching parent 
      $log.info(vm.lastNodeSelected); 
      var cnt = children.length; 
      for (var i = 0; i < cnt; i++) { 
       if (children[i].children) { 
        var innerCnt = children[i].children.length; 
        for (var c = 0; c < innerCnt; c++) { 
         if (children[i].children[c].name === vm.lastNodeSelected) { 
          children[i].children[c].children = vm.newChildData; 

         } 
        } 
       } 
      } 

      //wrap back in object and assign to ngModel 
      vm.updatedList = { children }; 
      // $log.info(updatedList);  

      vm.treeData2 = vm.updatedList; 
      $timeout(function() { 
       $scope.$apply(function() { 
        vm.treeData = vm.updatedList; 
       })} , 0); 
     } 

     vm.getAggregateInfo = function (node) { 

      vm.lastNodeSelected = node.name; 
      loadData(); 
      // $log.info(vm.lastNodeSelected); 
     }; 


    } 

})(); 

Es folgt die treeview Richtlinie.

Was ich sehe, ist, wenn ich auf den Vorfall Kontrollkästchen das JavaScript-Objekt aktualisiert wird. Sie können dies sowohl in der Ausgabe als auch in der zweiten Baumansicht sehen, die gebunden wird, sobald das Kontrollkästchen aktiviert ist.

Ich vermute, das Problem hängt mit dem $ Digest-Zyklus des Ereignisses zusammen und der Baum wird nicht benachrichtigt, um tatsächlich zu aktualisieren. Ich habe versucht, wie Sie in der Steuerung mit einem $scope.$apply() in einem Timeout eingehüllt sehen sehen, aber dies hat nicht funktioniert, um den ursprünglichen Baum zu aktualisieren.

Addierende Aktionen wie ein .push() zu den Array-Updates, jedoch versucht, ein neues Objekt in ein vorhandenes Array einzufügen scheint nicht zu funktionieren.

Haben Sie Vorschläge, wie Sie die Struktur der untergeordneten Objekte aktualisieren und spiegeln können?

+0

Wenn ich richtig verstehe, möchten Sie treeview1, dann treeview2 auffüllen. In dieser Reihenfolge? Wenn ja, würde ich eine Zusage verwenden, um treeview1 zu laden und dann treeview2 in den Controller zu laden. Dann werden Ihre Anweisungen auch in dieser Reihenfolge "geladen" – Frode

+0

Treeview 2 ist nur zum Testen da. Es stellt die korrekte Datenstruktur des Objekts dar, sobald die verschachtelten Objekte hinzugefügt wurden. Die erwartete Ausgabe wäre, sobald die neue Sammlung der ursprünglichen Liste hinzugefügt wird. Treeview 1 würde aktualisieren, die verschachtelten Elemente (in diesem Fall die Daten unter Vorfall) – rlcrews

+0

Ich kann keine Verwendung von Versprechen in Ihrem Code sehen. Es riecht nach Versprechensessen. Kennen Sie sich mit $ q aus? – Frode

Antwort

0

Hier ist eine leicht modifizierte Plunker, um das Problem zu markieren (und teilweise zu beheben).

Ich habe die folgenden Zeilen in der link Funktion in der branch Richtlinie:

scope.$watch('b', function (newvalue, oldvalue) { 
    if (!oldvalue.children && newvalue.children) { 
     scope.visible = true; 
     element.append('<tree src="b" filter="filter({ object: object, isSelected: isSelected })"></tree>'); 
     $compile(element.contents())(scope); 
    } 
}, true); 

Die link Funktion nicht erneut aufgerufen wird, wenn die Baumstruktur aktualisiert wird. Wenn also neue Kinder hinzugefügt werden, werden diese nicht für Angular kompiliert.