2016-07-10 5 views
0

Ich habe eine Tabelle mit drei verschiedenen Ebenen von Daten, wenn ich die Kind-Ebene von Daten mit einem ng-Klick die Daten angezeigt werden angezeigt ok, aber wenn ich die Enkel-Ebene die Daten nicht aufrufen angezeigt, die Antwort meines WS ist in Ordnung, weil ich es in meiner Konsole gespeichert sehe, so dass ich nach einiger Zeit erkannte, dass ich meine ng-repeats verschachteln muss, um die Daten von der Enkel-Ebene anzuzeigen, aber ich bekomme nicht wie tu es, ich habe auch die ng-repeat-start-Anweisung geprüft, weiß aber nicht, ob sie auf meine htlm-Struktur zutrifft, das habe ich aus meiner Sicht.Verschachtelte ng-Wiederholung in HTML-Tabelle

<table class="table table-bordered drilldown-table" id="fixTable" style="height: 505px"> 

    <tbody ng-repeat="cat in (exportData.result.slice(0, exportData.result.length-2))" > 

    <tr class="parent"> 

     <td ng-click="drillDownSubcategoriesCat(cat.merchMetrics.DEPT_NBR,cat.merchMetrics.CATG_GRP_NBR,cat.merchMetrics.DEPT_CATG_NBR)" drill-down>+</td> 

     <td style="text-align: left">{{cat.merchMetrics.DEPT_CATG_DESC}}</td> 

     <!--SALES--> 
     <td>{{cat.merchMetrics.SALES_AMOUNT_LW | number : 2}}</td> 
     <td>{{cat.merchMetrics.SALES_LW_CHG_LY}}%</td> 
     <td>{{cat.merchMetrics.SALES_L4W_CHG_LY}}%</td> 
     <td>{{cat.merchMetrics.SALES_L13W_CHG_LY}}%</td> 
     <td>{{cat.merchMetrics.SALES_L52W_CHG_LY}}%</td> 
     <td>{{cat.merchMetrics.SALES_LW_VS_L13W}}</td> 
    </tr> 

    <tr ng-repeat="subcat in drillDownSubcatCatList['D' + cat.merchMetrics.DEPT_NBR + 'CG' + cat.merchMetrics.CATG_GRP_NBR + 'C' + cat.merchMetrics.DEPT_CATG_NBR]" class="child" ng-if="!$last" style="background-color: #f3eee9"> 

     <td ng-click="drillDownCategoryItemsCat(subcat.merchMetrics.DEPT_NBR, subcat.merchMetrics.CATG_GRP_NBR, subcat.merchMetrics.DEPT_CATG_NBR, subcat.merchMetrics.DEPT_SUBCATG_NBR)" drill-down>+</td> 

     <td style="text-align: left; padding-left: 25px">{{subcat.merchMetrics.DEPT_SUBCATG_DESC}}</td> 

     <!--SALES--> 
     <td>{{subcat.merchMetrics.SALES_AMOUNT_LW | number : 2}}</td> 
     <td>{{subcat.merchMetrics.SALES_LW_CHG_LY}}%</td> 
     <td>{{subcat.merchMetrics.SALES_L4W_CHG_LY}}%</td> 
     <td>{{subcat.merchMetrics.SALES_L13W_CHG_LY}}%</td> 
     <td>{{subcat.merchMetrics.SALES_L52W_CHG_LY}}%</td> 
     <td>{{subcat.merchMetrics.SALES_LW_VS_L13W}}</td> 
    </tr> 

    <tr ng-repeat="items in drillDownCategoryItemCatList[nbrSubcatItem]" class="grandson" ng-if="!$last" style="background-color: #f3eee9"> 

     <td></td> 
     <td style="text-align: left; padding-left: 45px">{{items.merchMetrics.DEPT_SUBCATG_DESC}}}</td> 

     <!--SALES--> 
     <td>{{items.merchMetrics.SALES_AMOUNT_LW | number : 2}}</td> 
     <td>{{items.merchMetrics.SALES_LW_CHG_LY}}%</td> 
     <td>{{items.merchMetrics.SALES_L4W_CHG_LY}}%</td> 
     <td>{{items.merchMetrics.SALES_L13W_CHG_LY}}%</td> 
     <td>{{items.merchMetrics.SALES_L52W_CHG_LY}}%</td> 
     <td>{{items.merchMetrics.SALES_LW_VS_L13W}}</td> 

    </tr> 

</tbody> 

Um die Daten aus dem Kind und Enkel Ebene I-Funktionen aufrufen zu generieren.

$scope.drillDownSubcatCatList = {}; 

    $scope.subcatNbr = ''; 

    $scope.drillDownSubcategoriesCat = function (dept,group,catg) { 

     $scope.nbr1 = [dept]; 
     $scope.nbr2 = [group]; 
     $scope.nbr3 = [catg]; 

     $scope.nbrSubcat = 'D' + $scope.nbr1 + 'CG' + $scope.nbr2 + 'C' + $scope.nbr3; 
     $scope.nbrSubcat.toString(); 

     $scope.subCategoryConst = ['Product Sales (Subcategory Rank)']; 
     $scope.drillDownRecords = "5"; 

     console.log($scope.nbr1); 
     console.log($scope.nbr2); 
     console.log($scope.nbr3); 
     console.log("NBR: " + $scope.nbrSubcat); 

     if (!($scope.nbrSubcat in $scope.drillDownSubcatCatList)) { 

      $scope.loadViewCategories = false; 
      $scope.graphLoading = "loading"; 
      searchFactory.search('merchandise', 

       { 
        timeStamp: $scope.dateTime, 
        timeFrameType: $scope.whenType, 
        custMembSelectionType: $scope.customerType, 
        locationSelectionType: $scope.locationType, 
        merchandiseSelectionType: "Category", 
        startYear: $scope.whenStartParentYear, 
        endYear: $scope.whenStartParentYear, 
        startUnit: $scope.whenStartValue, 
        endUnit: $scope.whenStartValue, 
        comparator: $scope.locationType.indexOf('(Comp)', $scope.locationType.length - '(Comp)'.length) !== -1, 
        locationSelections: $scope.locationSelected, 
        merchandiseSelections: [$scope.nbrSubcat], 
        custMembSelections: $scope.customerSelected, 
        metricSelections: $scope.subCategoryConst, 
        rankOrder: $scope.drillDownRecords 


       }).success(function (data) { 


        console.log("drillDownSubcategories OK"); 
        $scope.loadViewCategories = true; 
        $scope.graphLoading = "white"; 
        $scope.canvasContent = true; 
        $scope.exportDataCategoryDrillDown = data; 
        $scope.metricSelected = $scope.filters.baropt.displayName; 

        if (data.error) { 
         $scope.noData = "There are no results based on your selected dropdowns. Please change your selection."; 
         $scope.data = undefined; 
         $scope.hasError = true; 
        } 

        $scope.isExportDisabled = 'auto'; 

        if (!$scope.drillDownSubcatCatList[$scope.nbrSubcat]) { 

         $scope.drillDownSubcatCatList[$scope.nbrSubcat] = $scope.exportDataCategoryDrillDown.result; 
        } 



       }).error(function (ret, status) { 
        console.log(ret, status); 
        if (status == 500 || status == 0) { 
         if (ret.error.indexOf("Filter criteria not found!") > -1 || ret.error.indexOf("Bad Selections!") > -1) { 
          $scope.errorMessage = "The combination of dropdowns you selected is invalid. Please select a different combination."; 
         } else { 
          $scope.errorMessage = "The database may be down. Please contact Data Cafe Development Team - Applications for help."; 
         } 
        } else if (status == 400) { 
         $scope.errorMessage = "There was a bad request sent to the database. Please contact Data Cafe Development Team - Applications for help."; 
        } else { 
         $scope.errorMessage = "There was an error while trying to process your request. Please contact Data Cafe Development Team - Applications for help."; 
        } 
        $scope.hasError = true; 
        $scope.graphLoading = "white"; 
        $scope.canvasContent = true; 
        $scope.showCaptions = false; 
       } 
      ); 
     } 

     if($scope.nbrSubcat in $scope.drillDownSubcatCatList) { 
      console.log("--------------- " + $scope.nbrSubcat); 
      console.log("RETURN DD SUBCATEGORY LIST: ", $scope.drillDownSubcatCatList); 
     } 

    } 

Und dies ist die zweite Funktion:

$scope.drillDownCategoryItemCatList = {}; 

    $scope.drillDownCategoryItemsCat = function (dept,group,catg,subcat) { 

     $scope.nbr1 = [dept]; 
     $scope.nbr2 = [group]; 
     $scope.nbr3 = [catg]; 
     $scope.nbr4 = [subcat]; 

     $scope.nbrSubcatItem = 'D' + $scope.nbr1 + 'CG' + $scope.nbr2 + 'C' + $scope.nbr3 + 'SC' + $scope.nbr4; 
     $scope.nbrSubcatItem.toString(); 

     $scope.ItemsConst = ['Product Sales (Item Rank)']; 
     $scope.drillDownRecords = "5"; 

     console.log($scope.nbr1); 
     console.log($scope.nbr2); 
     console.log($scope.nbr3); 
     console.log($scope.nbr4); 
     console.log("NBR: " + $scope.nbrSubcatItem); 

     if (!($scope.nbrSubcatItem in $scope.drillDownCategoryItemCatList)) { 

      $scope.loadViewCategories = false; 
      $scope.graphLoading = "loading"; 
      searchFactory.search('merchandise', 

       { 
        timeStamp: $scope.dateTime, 
        timeFrameType: $scope.whenType, 
        custMembSelectionType: $scope.customerType, 
        locationSelectionType: $scope.locationType, 
        merchandiseSelectionType: "SubCategory", 
        startYear: $scope.whenStartParentYear, 
        endYear: $scope.whenStartParentYear, 
        startUnit: $scope.whenStartValue, 
        endUnit: $scope.whenStartValue, 
        comparator: $scope.locationType.indexOf('(Comp)', $scope.locationType.length - '(Comp)'.length) !== -1, 
        locationSelections: $scope.locationSelected, 
        merchandiseSelections: [$scope.nbrSubcatItem], 
        custMembSelections: $scope.customerSelected, 
        metricSelections: $scope.ItemsConst, 
        rankOrder: $scope.drillDownRecords 


       }).success(function (data) { 


        console.log("drillDownCategortyItems OK"); 
        $scope.loadViewCategories = true; 
        $scope.graphLoading = "white"; 
        $scope.canvasContent = true; 
        $scope.exportDataCategoryItemDrillDown = data; 
        $scope.metricSelected = $scope.filters.baropt.displayName; 

        if (data.error) { 
         $scope.noData = "There are no results based on your selected dropdowns. Please change your selection."; 
         $scope.data = undefined; 
         $scope.hasError = true; 
        } 

        $scope.isExportDisabled = 'auto'; 

        if (!$scope.drillDownCategoryItemCatList[$scope.nbrSubcatItem]) { 

         $scope.drillDownCategoryItemCatList[$scope.nbrSubcatItem] = $scope.exportDataCategoryItemDrillDown.result; 

        } 


       }).error(function (ret, status) { 
        console.log(ret, status); 
        if (status == 500 || status == 0) { 
         if (ret.error.indexOf("Filter criteria not found!") > -1 || ret.error.indexOf("Bad Selections!") > -1) { 
          $scope.errorMessage = "The combination of dropdowns you selected is invalid. Please select a different combination."; 
         } else { 
          $scope.errorMessage = "The database may be down. Please contact Data Cafe Development Team - Applications for help."; 
         } 
        } else if (status == 400) { 
         $scope.errorMessage = "There was a bad request sent to the database. Please contact Data Cafe Development Team - Applications for help."; 
        } else { 
         $scope.errorMessage = "There was an error while trying to process your request. Please contact Data Cafe Development Team - Applications for help."; 
        } 
        $scope.hasError = true; 
        $scope.graphLoading = "white"; 
        $scope.canvasContent = true; 
        $scope.showCaptions = false; 
       } 
      ); 
     } 

     if($scope.nbrSubcatItem in $scope.drillDownCategoryItemCatList) { 

      console.log("LIST FROM CATEGORY TO ITEM LEVEL: ", $scope.drillDownCategoryItemCatList); 
     } 

    } 

Wie ich schon erwähnt, die Eltern und das Kind Ebene angezeigt ok, so dass jede Idee, wie kann ich das Nest der ng-repeat der um um zu erlauben, dass mein Enkel Level angezeigt wird?

+0

Wir haben keine Ahnung, wie Sie 'DrillDownCategoryItemCatList' im Controller generieren. Zeige alle relevanten Code – charlietfl

+0

Hallo, ich aktualisiere meinen Code, ich füge die beiden Funktionen die ich rufe hinzu und aktualisiere auch den ng-klick auf den html weil ich dort einige Parameter verwende. @charlietfl – kennechu

+0

Wäre besser, wenn Sie eine jsfiddle/plnkr bereitstellen. – developer033

Antwort

1

Hier ist etwas seltsam, dass Sie eine einzelne Tabelle in der Benutzeroberfläche benötigen, aber das zugrunde liegende Modell ist ein dreifach verschachteltes Objekt. ng-repeat ist nicht auf geschachtelte DOM-Ebenen verschachtelt.

Die Art, wie ich die Implementierung empfehlen würde, ist die Verwendung eines angularen Filters, der alle Ihre Daten in ein einziges Array umwandelt, das Sie ng-repeat aufrufen können.

Ihr Controller hat wayyyyy zu viel Logik drin. Und ich denke, das trägt zu den Schwierigkeiten bei. Im Allgemeinen sollte der Controller für die Anzeige von Daten verantwortlich sein, die von eckigen Diensten bereitgestellt werden. Die eckigen Dienste sollten die Daten so bereitstellen, dass sie für die Controller leicht zu konsumieren sind.

Wenn Sie feststellen, dass Sie verschachtelte if-Anweisungen, xhr-Anforderungen und Fehlerbehandlung innerhalb des Controllers erstellen, dann machen Sie etwas falsch. All dies sollte auf mehrere Dienste umgestaltet werden (jeder Dienst sollte eine EINZIGE Verantwortung haben). Dann sollte einer der Dienste dem Controller Daten zur Verfügung stellen, die leicht zu konsumieren sind.

Dies ist ein bisschen eine vage Antwort, und nicht wirklich ein einfacher. Ich denke, dass die Probleme, die Sie haben, davon herrühren, nicht vollständig zu verstehen, wie Angular das MVC-Muster implementiert.