AngularJS: ng-repeat list is not updated when a model element is spliced from the model array -
i have 2 controllers , share data between them app.factory function.
the first controller adds widget in model array (pluginsdisplayed) when link clicked. widget pushed array , change reflected view (that uses ng-repeat show array content):
<div ng-repeat="plugind in pluginsdisplayed"> <div k2plugin pluginname="{{plugind.name}}" pluginid="{{plugind.id}}"></div> </div>
the widget built upon 3 directives, k2plugin, remove , resize. remove directive adds span template of k2plugin directive. when said span clicked, right element shared array deleted array.splice()
. shared array correctly updated, change not reflected in view. however, when element added, after remove, view refreshed correctly , previously-deleted element not shown.
what getting wrong? explain me why doesn't work? there better way i'm trying angularjs?
this 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 1 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>
this 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 element in array (var = 0; < len; += 1) { if ($scope.pluginsdisplayed[i].id === this.pluginid) { index = i; break; } } // remove element if (index !== -1) { console.log ("removing element 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"); // won't work immediately. attribute pluginname undefined // called. scope.pluginname = "loading..."; scope.pluginid = attrs.pluginid; // observe changes interpolated attribute attrs.$observe('pluginname', function(value) { console.log('pluginname has changed value ' + value); scope.pluginname = attrs.pluginname; }); // observe changes interpolated attribute attrs.$observe('pluginid', function(value) { console.log('pluginid has changed value ' + 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); }) }; });
whenever form of operation outside of angularjs, such doing ajax call jquery, or binding event element have here need let angularjs know update itself. here code change need do:
app.directive("remove", function () { return function (scope, element, attrs) { element.bind ("mousedown", function () { scope.remove(element); scope.$apply(); }) }; }); app.directive("resize", function () { return function (scope, element, attrs) { element.bind ("mousedown", function () { scope.resize(element); scope.$apply(); }) }; });
here documentation on it: https://docs.angularjs.org/api/ng/type/$rootscope.scope#$apply
Comments
Post a Comment