title: AngularJS: ng-repeat list is not updated when a model element is spliced from the model array
body: <p>I have two controllers and share data between them with an app.factory function.</p>
  
  <p>The first controller adds a widget in the model array (pluginsDisplayed) when a link is clicked. The widget is pushed into the array and this change is reflected into the view (that uses ng-repeat to show the array content):</p>
  
  <pre><code>&lt;div ng-repeat="pluginD in pluginsDisplayed"&gt;
      &lt;div k2plugin pluginname="{{pluginD.name}}" pluginid="{{pluginD.id}}"&gt;&lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>The widget is built upon three directives, k2plugin, remove and resize. The remove directive adds a span to the template of the k2plugin directive. When said span is clicked, the right element into the shared array is deleted with <code>Array.splice()</code>. The shared array is correctly updated, but the change is <strong>not</strong> reflected in the view. However, when another element is added, after the remove, the view is refreshed correctly and the previously-deleted element is not shown.</p>
  
  <p>What am I getting wrong? Could you explain me why this doesn't work?
  Is there a better way to do what I'm trying to do with AngularJS?</p>
  
  <p>This is my index.html:</p>
  
  <pre><code>&lt;!doctype html&gt;
  &lt;html&gt;
      &lt;head&gt;
          &lt;script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"&gt;
          &lt;/script&gt;
          &lt;script src="main.js"&gt;&lt;/script&gt;
      &lt;/head&gt;
      &lt;body&gt;
          &lt;div ng-app="livePlugins"&gt;
              &lt;div ng-controller="pluginlistctrl"&gt;
                  &lt;span&gt;Add one of {{pluginList.length}} plugins&lt;/span&gt;
                  &lt;li ng-repeat="plugin in pluginList"&gt;
                      &lt;span&gt;&lt;a href="" ng-click="add()"&gt;{{plugin.name}}&lt;/a&gt;&lt;/span&gt;
                  &lt;/li&gt;
              &lt;/div&gt;
              &lt;div ng-controller="k2ctrl"&gt;
                  &lt;div ng-repeat="pluginD in pluginsDisplayed"&gt;
                      &lt;div k2plugin pluginname="{{pluginD.name}}" pluginid="{{pluginD.id}}"&gt;&lt;/div&gt;
                  &lt;/div&gt;
              &lt;/div&gt;
          &lt;/div&gt;
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>This is my main.js:</p>
  
  <pre><code>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 &lt; 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: "&lt;div&gt;{{pluginname}} &lt;span resize&gt;_&lt;/span&gt; &lt;span remove&gt;X&lt;/span&gt;" +
                         "&lt;div&gt;Plugin DIV&lt;/div&gt;" +
                    "&lt;/div&gt;",
          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);
          })
      };
  });
  </code></pre>