Ich habe zwei Arrays, die als "Objekte" und "AppliedObjects" bezeichnet werden. Ich versuche, in Javascript und / oder Angular eine elegante Methode zu finden, um Objekte von einem Array in ein anderes zu verschieben.

Anfangs habe ich so etwas gemacht:

   $scope.remove = function () {
        angular.forEach($scope.appliedObjects, function (element, index) {
            if (element.selected) {
                element.selected = false;
                $scope.objects.push(element);
                $scope.appliedObjects.splice(index, 1);
            }
        });
    }

   $scope.add= function () {
        angular.forEach($scope.objects, function (element, index) {
            if (element.selected) {
                element.selected = false;
                $scope.appliedObjects.push(element);
                $scope.objects.splice(index, 1);
            }
        });
    }

Aber dann wurde mir klar, dass, wenn der Wert aus dem Schleifenarray entfernt wurde, nicht jedes andere Element hinzugefügt oder entfernt werden würde, da es nach Index ging.

Dann habe ich versucht, ein temporäres Array zu verwenden, um die Liste der Elemente zu speichern, die hinzugefügt oder entfernt werden sollen, und ich bekam seltsame referenzielle Probleme.

Ich fange an, ein wenig darüber nachzudenken, was die beste Lösung für dieses Problem wäre ... jede Hilfe und / oder Anleitung wäre sehr dankbar.

16
morganpdx 8 Aug. 2015 im 02:23

6 Antworten

Beste Antwort
function moveElements(source, target, moveCheck) {
    for (var i = 0; i < source.length; i++) {
        var element = source[i];
        if (moveCheck(element)) {
            source.splice(i, 1);
            target.push(element);
            i--;
        }
    } 
}

function selectionMoveCheck(element) {
   if (element.selected) {
       element.selected = false;
       return true;
   }
}

$scope.remove = function () {
    moveElements($scope.appliedObjects, $scope.objects, selectionMoveCheck);
}

$scope.add = function () {
    moveElements($scope.objects, $scope.appliedObjects, selectionMoveCheck);
}
13
Artem 7 Aug. 2015 im 23:55

Dies ist vielleicht keine faire Antwort, aber wenn Sie feststellen, dass Sie eine Menge komplizierter Objekt- / Array-Manipulationen durchführen, sollten Sie sich unbedingt die lodash- oder Unterstrichbibliothek ansehen. dann könnten Sie dies mit on liner lösen:

//lodash remove function
appliedObjects.push.apply( appliedObjects, _.remove(objects, { 'selected': true}));

//or if you want to insert in the beginning of the list:
appliedObjects.splice(0, 0, _.remove(objects, { 'selected': true}));
0
micnil 8 Aug. 2015 im 00:20

Wenn Sie einfach ein ganzes Array verschieben möchten, können Sie Folgendes tun:

appliedObjects = objects;
objects = []

Natürlich wird es nicht funktionieren, wenn sie Parameter einer Funktion wären! Andernfalls kann ich keinen anderen Weg als das Kopieren in der Schleife sehen, z.

while (objects.length) {
    appliedObjects.push(objects[0]);
    objects.splice(0,1);
}

Oder wenn du Funktionscode magst :):

while (objects.length) appliedObjects.push(objects.splice(0,1));

Überprüfen Sie die Geige http://jsfiddle.net/060ywajm/

0
Zbyszek Swirski 1 Sept. 2015 im 01:09

Wenn ein Konstrukt zu viel automatisch ausführt (wie in diesem Fall forEach oder sogar eine for-Schleife), verwenden Sie ein primitiveres Konstrukt, mit dem Sie klar sagen können, was passieren soll, ohne das Konstrukt umgehen zu müssen. Mithilfe einer while-Schleife können Sie ausdrücken, was geschehen muss, ohne auf das Sichern oder anderweitige Anwenden von Problemumgehungen zurückgreifen zu müssen:

    function moveSelected(src, dest)  {
        var i = 0;
        while ( i < src.length ) {
            var item = src[i];
            if (item.selected) {
                src.splice(i,1);
                dest.push(item);
            }
            else i++;
        }
    }
6
Ed Staub 8 Aug. 2015 im 01:37

Wenn Sie das Array während der Iteration ändern, werden Sie immer einige Elemente vermissen.

Eine Möglichkeit besteht darin, ein drittes Array zu verwenden, um die Referenzen der Objekte zu speichern, die aus dem Array entfernt werden müssen:

// "$scope.add" case
var objectsToRemove = [];

$scope.objects.forEach(function (value) {
  if (value.selected) {
    value.selected = false;
    $scope.appliedObjects.push(value);
    objectsToRemove.push(value);
  }
});

objectsToRemove.forEach(function (value) {
  $scope.objects.splice($scope.objects.indexOf(value), 1);
});
0
Brunt 7 Aug. 2015 im 23:47

Dies ist ein erster Durchgang zu dem, was meiner Meinung nach für Sie funktionieren wird. Ich bin gerade dabei, eine Testseite zu erstellen, damit ich die Genauigkeit der Arbeit testen und das optimierte Ergebnis aktualisieren kann, was hoffentlich nicht der Fall sein wird.

EDIT: Ich habe es ausgeführt und es scheint zu tun, was Sie wollen, wenn ich das Problem richtig verstehe. Es gab einige Syntaxfehler, die ich herausgeschnitten habe.

Hier ist der Plunk mit dem komprimierten, bereinigten Code http://plnkr.co/edit/K7XuMu?p= Vorschau

HTML

<button ng-click="transferArrays(objects, appliedObjects)">Add</button>
<button ng-click="transferArrays(appliedObjects, objects)">Remove</button>

JS

$scope.transferArrays = function (arrayFrom, arrayTo) {
var selectedElements;
selectedElements = [];
angular.forEach(arrayFrom, function(element) {
  if (element.isSelected) {
    element.isSelected = false;
    selectedElements.push(element);
  }
});
angular.forEach(selectedElements, function(element) {
  arrayTo.push(arrayFrom.splice(
    arrayFrom.map(function(x) {
      return x.uniqueId;
    })
    .indexOf(element.uniqueId), 1));
});
};

Alter Code

$scope.remove = function () {
        var selectedElements;
        selectedElements = [];
        angular.forEach($scope.appliedObjects, function (element) {
            if (element.isSelected) {
                element.isSelected = false;
                selectedElements.push(element);
            }
        });
        angular.forEach(selectedElements, function (element) {
            $scope.objects.push($scope.appliedObjects.splice(
                $scope.appliedObjects.map(function  (x) { return x.uniqueId; })
                .indexOf(element.uniqueId), 1));
        });
    };

$scope.add = function () {
        var selectedElements;
        selectedElements = [];
        angular.forEach($scope.objects, function (element) {
            if (element.isSelected) {
                element.isSelected = false;
                selectedElements.push(element);
            }
        });
        angular.forEach(selectedElements, function (element) {
            $scope.appliedObjects.push($scope.objects.splice(
                $scope.objects.map(function  (x) { return x.uniqueId; })
                .indexOf(element.uniqueId), 1));
        });
    };
0
tuckerjt07 8 Aug. 2015 im 00:54