Ich habe zwei Controller und teile Daten zwischen ihnen mit einer app.factory-Funktion.
Der erste Controller fügt dem Modellarray ein Widget hinzu (pluginsDisplayed), wenn auf einen Link geklickt wird. Das Widget wird in das Array verschoben und diese Änderung wird in die Ansicht übernommen (die ng-repeat verwendet, um den Array-Inhalt anzuzeigen):
<div ng-repeat="pluginD in pluginsDisplayed">
<div k2plugin pluginname="{{pluginD.name}}" pluginid="{{pluginD.id}}"></div>
</div>
Das Widget basiert auf drei Anweisungen: k2plugin, remove und resize. Die Direktive remove entfernt fügt der Vorlage der Direktive k2plugin eine Spanne hinzu. Wenn auf diesen Bereich geklickt wird, wird das richtige Element im freigegebenen Array mit gelöscht Array.splice()
. Das freigegebene Array wird korrekt aktualisiert, die Änderung wird jedoch nicht in der Ansicht angezeigt. Wenn jedoch nach dem Entfernen ein weiteres Element hinzugefügt wird, wird die Ansicht korrekt aktualisiert und das zuvor gelöschte Element wird nicht angezeigt.
Was mache ich falsch? Können Sie mir erklären, warum das nicht funktioniert? Gibt es einen besseren Weg, um das zu tun, was ich mit AngularJS versuche?
Dies ist meine index.html:
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js">
</script>
<script src="main.js"></script>
</head>
<body>
<div ng-app="livePlugins">
<div ng-controller="pluginlistctrl">
<span>Add one of {{pluginList.length}} plugins</span>
<li ng-repeat="plugin in pluginList">
<span><a href="" ng-click="add()">{{plugin.name}}</a></span>
</li>
</div>
<div ng-controller="k2ctrl">
<div ng-repeat="pluginD in pluginsDisplayed">
<div k2plugin pluginname="{{pluginD.name}}" pluginid="{{pluginD.id}}"></div>
</div>
</div>
</div>
</body>
</html>
Dies ist meine main.js:
var app = angular.module ("livePlugins",[]);
app.factory('Data', function () {
return {pluginsDisplayed: []};
});
app.controller ("pluginlistctrl", function ($scope, Data) {
$scope.pluginList = [{name: "plugin1"}, {name:"plugin2"}, {name:"plugin3"}];
$scope.add = function () {
console.log ("Called add on", this.plugin.name, this.pluginList);
var newPlugin = {};
newPlugin.id = this.plugin.name + '_' + (new Date()).getTime();
newPlugin.name = this.plugin.name;
Data.pluginsDisplayed.push (newPlugin);
}
})
app.controller ("k2ctrl", function ($scope, Data) {
$scope.pluginsDisplayed = Data.pluginsDisplayed;
$scope.remove = function (element) {
console.log ("Called remove on ", this.pluginid, element);
var len = $scope.pluginsDisplayed.length;
var index = -1;
// Find the element in the array
for (var i = 0; i < len; i += 1) {
if ($scope.pluginsDisplayed[i].id === this.pluginid) {
index = i;
break;
}
}
// Remove the element
if (index !== -1) {
console.log ("removing the element from the array, index: ", index);
$scope.pluginsDisplayed.splice(index,1);
}
}
$scope.resize = function () {
console.log ("Called resize on ", this.pluginid);
}
})
app.directive("k2plugin", function () {
return {
restrict: "A",
scope: true,
link: function (scope, elements, attrs) {
console.log ("creating plugin");
// This won't work immediately. Attribute pluginname will be undefined
// as soon as this is called.
scope.pluginname = "Loading...";
scope.pluginid = attrs.pluginid;
// Observe changes to interpolated attribute
attrs.$observe('pluginname', function(value) {
console.log('pluginname has changed value to ' + value);
scope.pluginname = attrs.pluginname;
});
// Observe changes to interpolated attribute
attrs.$observe('pluginid', function(value) {
console.log('pluginid has changed value to ' + value);
scope.pluginid = attrs.pluginid;
});
},
template: "<div>{{pluginname}} <span resize>_</span> <span remove>X</span>" +
"<div>Plugin DIV</div>" +
"</div>",
replace: true
};
});
app.directive("remove", function () {
return function (scope, element, attrs) {
element.bind ("mousedown", function () {
scope.remove(element);
})
};
});
app.directive("resize", function () {
return function (scope, element, attrs) {
element.bind ("mousedown", function () {
scope.resize(element);
})
};
});
quelle
Wenn Sie
$scope.$apply();
gleich danach ein hinzufügen$scope.pluginsDisplayed.splice(index,1);
danach , funktioniert es.Ich bin nicht sicher, warum dies geschieht, aber wenn AngularJS nicht weiß, dass sich der $ -Bereich geändert hat, muss $ apply manuell aufgerufen werden. Ich bin auch neu bei AngularJS und kann dies nicht besser erklären. Ich muss auch mehr darüber nachdenken.
Ich habe diesen großartigen Artikel gefunden , der es ganz richtig erklärt. Hinweis: Ich denke, es ist möglicherweise besser, ng-click (docs) zu verwenden, als an "mousedown" zu binden. Ich habe hier eine einfache App geschrieben ( http://avinash.me/losh , Quelle http://github.com/hardfire/losh ), die auf AngularJS basiert. Es ist nicht sehr sauber, aber es könnte hilfreich sein.
quelle
Ich hatte das gleiche Problem. Das Problem war, dass 'ng-controller' zweimal definiert wurde (im Routing und auch im HTML).
quelle
Entfernen Sie "Spur nach Index" aus der ng-Wiederholung und es würde das DOM aktualisieren
quelle
Es gibt einen einfachen Weg, das zu tun. Sehr leicht. Da habe ich das bemerkt
Entfernt alle $ scope.yourModel-Array-Listen, die Sie so ausführen können
Das $ scope.yourModel wird mit den geklonten Objekten aktualisiert.
Hoffentlich hilft das.
quelle