Saya memiliki dua pengontrol dan berbagi data di antara mereka dengan fungsi app.factory.
Pengontrol pertama menambahkan widget dalam larik model (pluginsDisplayed) saat tautan diklik. Widget didorong ke dalam array dan perubahan ini tercermin ke dalam tampilan (yang menggunakan ng-repeat untuk menampilkan konten array):
<div ng-repeat="pluginD in pluginsDisplayed">
<div k2plugin pluginname="{{pluginD.name}}" pluginid="{{pluginD.id}}"></div>
</div>
Widget ini dibangun di atas tiga arahan, k2plugin, hapus dan ubah ukuran. Perintah remove menambahkan rentang ke template direktif k2plugin. Ketika span tersebut diklik, elemen yang tepat ke dalam array bersama akan dihapus Array.splice()
. Array bersama diperbarui dengan benar, tetapi perubahannya tidak tercermin dalam tampilan. Namun, ketika elemen lain ditambahkan, setelah dihapus, tampilan disegarkan dengan benar dan elemen yang sebelumnya dihapus tidak ditampilkan.
Apa yang salah? Bisakah Anda menjelaskan mengapa ini tidak berhasil? Apakah ada cara yang lebih baik untuk melakukan apa yang saya coba lakukan dengan AngularJS?
Ini adalah index.html saya:
<!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>
Ini main.js saya:
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);
})
};
});
sumber
Jika Anda menambahkan
$scope.$apply();
hak setelahnya$scope.pluginsDisplayed.splice(index,1);
maka itu berhasil.Saya tidak yakin mengapa ini terjadi, tetapi pada dasarnya ketika AngularJS tidak tahu bahwa $ scope telah berubah, itu perlu memanggil $ apply secara manual. Saya juga baru mengenal AngularJS jadi tidak bisa menjelaskan ini lebih baik. Saya juga perlu melihat lebih dalam.
Saya menemukan artikel luar biasa ini yang menjelaskannya dengan cukup baik. Catatan: Saya pikir mungkin lebih baik menggunakan ng-click (docs) daripada mengikat ke "mousedown". Saya menulis aplikasi sederhana di sini ( http://avinash.me/losh , sumber http://github.com/hardfire/losh ) berdasarkan AngularJS. Memang tidak terlalu bersih, tapi mungkin bisa membantu.
sumber
Saya memiliki masalah yang sama. Masalahnya adalah karena 'ng-controller' didefinisikan dua kali (dalam perutean dan juga dalam HTML).
sumber
Hapus "track by index" dari ng-repeat dan itu akan menyegarkan DOM
sumber
Ada cara mudah untuk melakukannya. Sangat mudah. Sejak saya menyadarinya
menghapus semua daftar array $ scope.yourModel yang bisa Anda lakukan seperti ini
$ Scope.yourModel akan diperbarui dengan clonedObjects.
Semoga membantu.
sumber