2017-03-22 2 views
14

Jetzt in meinen Aufzeichnungen:Versuch, Array des Objekts zu manipulieren

14.3, 14.2 und 14.1 gehört zum Teil mit Id = 30.

Ich versuche, unten zu erreichen:

1) standardmäßig zunächst 2-IDs werden selected.Now wenn Benutzer versuchen id = 71 zu wählen, die 30 zu einem Teil gehört, dann sollten Benutzer nicht erlaubt werden, Wählen Sie id = 71, da die höhere Version von Teil 30 bereits ausgewählt ist, dh id = 76.

2) Jetzt wenn Benutzer deaktivieren ID = 77 (33) dann sollte Benutzer ID = 71 überprüfen dürfen, da jetzt kein anderes Teil ausgewählt ist, so sollte Benutzer erlaubt sein, alle Teil mit ID = 30 aber zu überprüfen Sobald der Benutzer ein anderes Teil auswählt, sollte der untere Teil deaktiviert werden.

Problem mit meinem Code:

1) Wenn ich 16.1 deaktivieren und versuchen, 14.2 zu überprüfen, dann bin ich nicht zu überprüfen, es erlaubt. Ich sollte erlauben, 14.2 zu überprüfen, da es jetzt keine anderen Teile gibt.

2) 16.1 und 14.3 sind standardmäßig aktiviert. Wenn ich jetzt 15.1 überprüfe und dann noch einmal 14.1 überprüfe, dann wird 14.3 unchecked, was falsch ist, da 14.3 unter Teil ID = 30 am höchsten ist, also sollte ich nicht in der Lage sein, 14.1 zu überprüfen.

var app = angular.module('myApp', []); 
 
     app.controller('myCtrl', function ($scope) { 
 
      $scope.myArray = [ 
 
       { 
 
        "id": 77, 
 
        "selected": true, 
 
        "part": 33, 
 
        "name": "16.1", 
 
       }, 
 
       { 
 
        "id": 76, 
 
        "part": 30, 
 
        "selected": true, 
 
        "name": "14.3", 
 
       }, 
 
       { 
 
        "id": 71, 
 
        "part": 30, 
 
        "selected": false, 
 
        "name": "14.2", 
 
       }, 
 
       { 
 
        "id": 70, 
 
        "part": 31, 
 
        "selected": false, 
 
        "name": "15.1", 
 
       }, 
 
       { 
 
        "id": 69, 
 
        "part": 30, 
 
        "selected": false, 
 
        "name": "14.1", 
 
       }, 
 
       { 
 
        "id": 68, 
 
        "part": 29, 
 
        "selected": false, 
 
        "name": "13.1", 
 
       }, 
 
       { 
 
        "id": 55, 
 
        "part": 26, 
 
        "selected": false, 
 
        "name": "12.1", 
 
       } 
 
       , 
 
       { 
 
        "id": 54, 
 
        "part": 25, 
 
        "selected": false, 
 
        "name": "11.2", 
 
       } 
 
       , 
 
       { 
 
        "id": 53, 
 
        "part": 25, 
 
        "selected": false, 
 
        "name": "11.1", 
 
       } 
 
      ]; 
 

 
      $scope.checkItem = function (item) { 
 
       if (item.selected) { 
 
        var index = $scope.myArray.map(m=>m.id).indexOf(item.id); 
 
        var previousPart = {}; 
 
        for (var i = index - 1; i >= 0; i--) { 
 
         if ($scope.myArray[i].selected) { 
 
          previousPart = $scope.myArray[i]; 
 
          break; 
 
         } 
 
        } 
 
        if (item.part != previousPart.part) { 
 
         for (var i = 0; i < $scope.myArray.length; i++) { 
 
          if (($scope.myArray[i].part == item.part && $scope.myArray[i].part != item.part) 
 
           && $scope.myArray[i].selected) { 
 
           $scope.myArray[i].selected = false; 
 
           break; 
 
          } 
 
         } 
 
        } 
 
        else 
 
         item.selected = false; 
 

 

 

 
       } 
 
      }; 
 
     });
<!DOCTYPE html> 
 
<html ng-app="myApp" ng-controller="myCtrl"> 
 
<head> 
 
    <title></title> 
 
    <meta charset="utf-8" /> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> 
 
</head> 
 
<body> 
 
    <div ng-repeat="item in myArray"> 
 
     <input ng-model="item.selected" ng-click="checkItem(item)" type="checkbox" />{{ item.name }} 
 
    </div> 
 
</body> 
 
</html>

+0

diese Arbeit in einem plunkr bekommen, und ich nehme einen Blick. –

Antwort

3

Ich würde einen anderen Weg nehmen. Die Trennung einiger Logik in einen Dienst hilft mir, den Code sauberer zu halten. Es wird einfacher zu warten, zu debuggen und zu testen. fiddle

var app = angular.module('myApp', []); 
 

 
app.controller('myCtrl', function($scope, myCollection) { 
 
    $scope.myArray = myCollection.items; 
 

 
    // Call function every time an item was checked 
 
    $scope.checkItem = function(item) { 
 

 
    // Remap collection items before and after 
 
    myCollection.mapCheckedItems(); 
 

 
    // Do something with the user's interaction only if there are 
 
    // different selected parts by definition 
 
    if (item.selected && myCollection.selectedPartsOnly.length > 1) { 
 

 
     // Iterate through the selected parts 
 
     myCollection.selectedPartsOnly.map(part => { 
 

 
     // Get the array of items belonging to the exact part number 
 
     var map = myCollection.selectedPartsMap[part]; 
 

 
     for (var j = map.length - 1; j > 0; j--) { 
 
      // By definition deselect all but the highest version. 
 
      // Happens if different part numbers selected simultaneously 
 
      map[j].selected = false; 
 
     } 
 
     }) 
 

 
    } 
 

 
    // Recalculate collection map to keep it up to date with the 
 
    // items' array 
 
    myCollection.mapCheckedItems(); 
 

 
    }; 
 

 
}); 
 

 
app.service('myCollection', function() { 
 
    // Init the collection object 
 
    var self = {}; 
 

 
    // Function to calculate and map items' dependencies 
 
    self.mapCheckedItems = mapCheckedItems; 
 

 
    // This holds a list of the selected unique part numbers 
 
    // Used to determine needed action easier. By definition if only 
 
    // one part number is selected and used to iterate through the map 
 
    self.selectedPartsOnly = []; 
 

 
    // This is the important dictionary where the part numbers is mapped 
 
    // to its child items. Easy access to items grouped by a part number 
 
    self.selectedPartsMap = {}; 
 

 
    // The actual array definition 
 
    self.items = [{ 
 
    "id": 77, 
 
    "selected": true, 
 
    "part": 33, 
 
    "name": "16.1", 
 
    }, { 
 
    "id": 76, 
 
    "part": 30, 
 
    "selected": true, 
 
    "name": "14.3", 
 
    }, { 
 
    "id": 71, 
 
    "part": 30, 
 
    "selected": false, 
 
    "name": "14.2", 
 
    }, { 
 
    "id": 70, 
 
    "part": 31, 
 
    "selected": false, 
 
    "name": "15.1", 
 
    }, { 
 
    "id": 69, 
 
    "part": 30, 
 
    "selected": false, 
 
    "name": "14.1", 
 
    }, { 
 
    "id": 68, 
 
    "part": 29, 
 
    "selected": false, 
 
    "name": "13.1", 
 
    }, { 
 
    "id": 55, 
 
    "part": 26, 
 
    "selected": false, 
 
    "name": "12.1", 
 
    }, { 
 
    "id": 54, 
 
    "part": 25, 
 
    "selected": false, 
 
    "name": "11.2", 
 
    }, { 
 
    "id": 53, 
 
    "part": 25, 
 
    "selected": false, 
 
    "name": "11.1", 
 
    }]; 
 

 
    // Init the helpers once on start. This will be executed only once 
 
    mapCheckedItems(); 
 

 
    // Return the service object to be accessed from the controller 
 
    return self; 
 

 
    // This function will create and update the objects mapping 
 
    function mapCheckedItems() { 
 

 
    // Reset the helpers 
 
    self.selectedPartsOnly = []; 
 
    self.selectedPartsMap = {}; 
 
     
 
    // Now we iterate through the selected items.   
 
    self.items 
 
     .filter(item => item.selected) 
 
     .map(item => { 
 

 
     // Map every selected item directly to one part number 
 
     mapSelectedParts(item); 
 

 
     // Determine what part numbers are in use. 
 
     mapSelectedPartsOnly(item.part); 
 
     }) 
 
    } 
 

 
    function mapSelectedPartsOnly(part) { 
 
    if (self.selectedPartsOnly.indexOf(part) == -1) 
 
     self.selectedPartsOnly.push(part); 
 
    } 
 

 
    function mapSelectedParts(item) { 
 
    if (!self.selectedPartsMap[item.part]) 
 
     self.selectedPartsMap[item.part] = []; 
 

 
    self.selectedPartsMap[item.part].push(item); 
 
    } 
 

 
})
<!DOCTYPE html> 
 
<html ng-app="myApp" ng-controller="myCtrl"> 
 
<head> 
 
    <title></title> 
 
    <meta charset="utf-8" /> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> 
 
</head> 
 
<body> 
 
    <div ng-repeat="item in myArray"> 
 
     <input ng-model="item.selected" ng-click="checkItem(item)" type="checkbox" />{{ item.name }} 
 
    </div> 
 
</body> 
 
</html>

+1

Upvoted für Ihre freundlichen Bemühungen um mir zu helfen.Vielen Dank. Es wäre wirklich hilfreich, wenn Sie eine Art von Kommentaren zu Ihrem Code auf, was es tut, damit ich verstehen kann :) –

+0

Hey @Learning, I ' habe meine Antwort mit einigen Kommentaren aktualisiert. Ich hoffe, Sie können besser verstehen, was vor sich geht. Obwohl ich persönlich denke, dass, wenn ein Code-Frieden Kommentare benötigt, dann ist es nicht sehr gut geschrieben, in diesem Fall ist es wahrscheinlich notwendig, weil das Anwendungsfall-Szenario zu abstrakt ist. –

+0

Vielen Dank für die Antwort und für die Erklärung auch und bitte helfen Sie weiter so :) –

1

ich eine Lösung erstellt habe, die Ihre beide Punkte erreichen und Ihre Probleme zu lösen, wie oben erwähnt.

Sie müssen checkItem Funktion in der Steuerung aktualisieren nur

$scope.checkItem = function(item) { 
    if (item.selected) { 
    var otherExists = $scope.myArray.filter(function(m) { 
     return ((m.part != item.part) && m.selected); 
    }).length; 
    var selfExists = $scope.myArray.filter(function(m) { 
     return ((m.part == item.part) && m.selected); 
    }).length - 1; 
    if (!!otherExists) { 
     if (!!selfExists) { 
     var selectedIsLower = $scope.myArray.filter(function(m) { 
      return ((m.part == item.part) && (m.id > item.id) && m.selected); 
     }).length; 
     if (!!selectedIsLower) { 
      item.selected = false; 
     } else { 
      $scope.myArray.filter(function(m) { 
      return (m.part == item.part); 
      }).forEach(function(m) { 
      m.selected = false; 
      }); 
      item.selected = true; 
     } 
     } else { 
     item.selected = false; 
     var allSelectedIds = []; 
     var allSelected = $scope.myArray.filter(function(m) { 
      return m.selected; 
     }); 
     allSelected.map(m => m.part).forEach(function(a) { 
      if (allSelectedIds.indexOf(a) < 0) { //skip duplicate id 
      allSelectedIds.push(a); 
      } 
     });; 
     if (allSelectedIds.length == 1) { 
      var maxEle = {}; 
      allSelected.forEach(function(m, count) { 
      if (maxEle.id) { 
       (maxEle.id > m.id) && (m.selected = false); 
      } 
      maxEle.id = m.id; 
      maxEle.count = count; 
      }); 
     } 
     item.selected = true; 
     } 
    } 
    } 
}; 

Arbeits fiddle

Verwandte Themen