Изменить массив в Angular не работает

Я получаю $scope.persons из серверной части. Я перечисляю это, используя ng-repeat.

Почему в моем случае массив не будет изменен при вызове $scope.openDeleteModal?

Функция вызывается, но с $scope.persons. ничего не происходит. Почему?

application.controller('listPersonController', function ($scope, personService) {
   personService.getPersons()
  .then(function(persons) {
      $scope.persons = persons;
  });

  $scope.openDeleteModal = function (personId, firstname, lastname, index) {
    console.log("click " + $scope.persons.length);
    $scope.persons.splice();
    console.log("click " + $scope.persons.length);
  };
});

Изменить:

Хорошо, я забыл о сплайсинге. Я использую это вместо

 $scope.openDeleteModal = function (personId, firstname, lastname, index) {
    console.log("click " + $scope.persons.length);
    $scope.persons = [];
    console.log("click " + $scope.persons.length);
  };

Первый регистрирует 3. Второй 0. Но я не вижу никаких изменений в области видимости (ng-repeat).

HTML:

<tbody>
   <tr ng-repeat="p in persons">
      <td>{{p.firstname}}</td>
      <td>{{p.lastname}}</td>
      <td><a href="#/register_person/{{p.id}}" class="tiny button radius" >Edit</a></td>
      <td>
        <a href="#" 
           ng-click="openDeleteModal(p.id, p.firstname, p.lastname, $index)"
           class="tiny button alert radius">Delete</a>
      </td>
   </tr>  
</tbody>

Обслуживание:

personService.getPersons = function($scope){
   var promise = $http.get("rest/person").then(function (response) {
        return response.data;
   });
   return promise;
};

Вот что {{persons}} просто под контроллером дает

[{"id":"5331c6f33004e1c8a26492a8","имя":"Карл","фамилия":"Свенссон"},{"id":"5331dfdb3004e1c8a26492ad","имя":"Дженни","фамилия":"Бертилссон "},{"id":"5331ee4e3004e1c8a26492ae","имя":"Босс","фамилия":"Густавссон"}]

Это также не меняется, когда я изменяю область действия

Изменить Попытка еще больше упростить материал.

application.controller('listPersonController', function ($scope, personService) {

  var personsList =  [{"id":"5331dfdb3004e1c8a26492ad","firstname":"Johnny","lastname":"Bravo"}];

  $scope.persons = personsList;

  $scope.openDeleteModal = function (personId, firstname, lastname, index) {
    console.log("click " + $scope.persons.length);
    $scope.persons.length = 0;
    personsList.length = 0;
    console.log("click " + $scope.persons.length);
  };
});

Изменить: HTML стал очень простым.

<div class="row" ng-controller="listPersonController" >
    <p ng-repeat="p in persons">{{p.firstname}} <a href="#" class="tiny button alert radius" ng-click="openDeleteModal(p.id, p.firstname, p.lastname, $index)" >Delete</a></p>
</div>

Еще проще. На моей странице значение var равно 3, и оно не обновляется при нажатии.

application.controller('listPersonController', function ($scope, personService) {

  $scope.var = "1";

  $scope.openDeleteModal = function () {
    $scope.var = "2";
  };

   $scope.var = "3";
});

Изменить: код работает должным образом при перемещении из ng-view. Почему это происходит?


person pethel    schedule 25.03.2014    source источник
comment
Разве splice не принимает 2 аргумента? .splice(index, 1)   -  person tymeJV    schedule 26.03.2014
comment
Ну... это, конечно, интересно - вид определенно должен обновиться. Просто для удовольствия - добавьте $scope.apply() в конце метода   -  person tymeJV    schedule 26.03.2014
comment
Ошибка: [$rootScope:inprog] $apply уже выполняется   -  person pethel    schedule 26.03.2014
comment
Хм... вид когда-нибудь обновляется? Через несколько секунд или другая функция Angular?   -  person tymeJV    schedule 26.03.2014
comment
не могли бы вы опубликовать некоторые из ваших HTML? как показано здесь: plnkr.co/edit/et9dxXR3cPUuthp7PxBN?p=preview ваш подход должен определенно работает   -  person Abraham P    schedule 26.03.2014
comment
@AbrahamP Я добавил HTML и метод службы.   -  person pethel    schedule 26.03.2014
comment
@tymeJV Представление должно быть обновлено, потому что для начала я получаю несколько строк в своей таблице.   -  person pethel    schedule 26.03.2014
comment
Я понимаю, но метод, который вы запускаете, должен запускать цикл дайджеста и применяться к представлению. Почему этого не происходит - загадка   -  person tymeJV    schedule 26.03.2014
comment
где в html ваш контроллер? в частности, есть ли другой контроллер (или директива) между тем, где ваш контроллер применяется к html, и где происходит ng-repeat, который также использует переменную person?   -  person Abraham P    schedule 26.03.2014
comment
‹div class=row ng-controller=listPersonController › находится над таблицей. Это очень простой html.   -  person pethel    schedule 26.03.2014
comment
Первые две вещи, которые я делаю при отладке angular, — это вызов window.myScope = $scope; в контроллере, чтобы я мог получить доступ ко всему в области с помощью инструментов отладки Chrome, вторая — отображать некоторые элементы <h1>{ $id }</h1>, чтобы увидеть, какой идентификатор области находится в данном элементе dom, а затем сравните это с идентификатором области, прикрепленной к свойству window.myScope.$id.   -  person BenCr    schedule 26.03.2014
comment
Если это внутри модального всплывающего окна с использованием angular-ui или чего-то подобного, у него, вероятно, есть новая дочерняя область.   -  person BenCr    schedule 26.03.2014
comment
@BenCr Возможно, вы правы, но я думаю, что устранил это? Или хотя бы пытается.   -  person pethel    schedule 26.03.2014
comment
попробуйте изменить коллекцию лиц как свойство объекта. поэтому $scope.persons = { list: [] } и привяжите к person.list. Я не могу вспомнить/не очень понимаю, почему это работает с дочерними областями, но это так.   -  person BenCr    schedule 26.03.2014
comment
Ну, вы можете легко подтвердить, что у вас есть, отобразив идентификаторы областей.   -  person BenCr    schedule 26.03.2014
comment
@BenCr Обе области в моем html выше имеют идентификатор 005. И контроллер ‹div›, и ‹p› внутри него   -  person pethel    schedule 26.03.2014
comment
@BenCr Каждый раз, когда я нажимаю «Удалить», идентификатор области изменяется. Звуки неправильные Но пока не знаю причину.   -  person pethel    schedule 26.03.2014
comment
есть ли шанс, что вы могли бы собрать plunk/jsfiddle?   -  person Abraham P    schedule 26.03.2014
comment
@AbrahamP Я заставляю его работать в плункере, но когда я перемещаю его в свое приложение, он перестает работать. Должен отлаживать больше.   -  person pethel    schedule 26.03.2014
comment
Когда я переместил код за пределы моего ng-view, он начал работать. Как ng-view может все испортить?   -  person pethel    schedule 26.03.2014
comment
в вашем определении маршрутов привязан ли ng-view к контроллеру? Делает ли этот контроллер что-нибудь с людьми?   -  person Abraham P    schedule 26.03.2014
comment
Это к контроллеру, отвечающему за верхнюю панель. Я не думаю, что это что-то делает с людьми. По крайней мере, не должно. Я должен проверить дубляж сегодня вечером.   -  person pethel    schedule 26.03.2014
comment
Вы пытались удалить href=# из ссылки? Это может привести к тому, что страница перейдет к самой себе и приведет к повторному созданию экземпляра контроллера и, следовательно, получению новой версии.   -  person BenCr    schedule 26.03.2014
comment
@BenCr Это очень хороший момент. Я вернусь к вам по этому поводу.   -  person pethel    schedule 26.03.2014
comment
@BenCr Ты решил мою проблему. Проблема заключалась в href=#. Давай, пиши ответ.   -  person pethel    schedule 26.03.2014


Ответы (2)


Удалите href="#" из ссылки, это, вероятно, приводит к тому, что страница переходит к самой себе и вызывает повторный экземпляр контроллера.

person BenCr    schedule 26.03.2014
comment
+1 У тебя получилось. Мы можем упустить тот факт, что обновление контроллера может изменить структуру данных. - person Nagaraj Tantri; 26.08.2015
comment
Вау, давно ответили. Я рад, что это помогло. - person BenCr; 26.08.2015
comment
правда, но я был новичком в angular, охотился за автоматическим поведением. У меня была кнопка с <a href="#" ..., теперь это <a href="javascript:void(0)".. - person Nagaraj Tantri; 26.08.2015

Метод splice не является деструктивным, если ему не переданы какие-либо аргументы.

Это означает, что хотя он и вернет объединенный (пустой) массив, он не перезапишет исходный массив.

Для вас это означает, что если вы хотите вызвать splice для очистки всего массива, вы должны вызвать:

$scope.persons = $scope.persons.splice()

Хотя (без ссылки на источник javascript) я считаю, что

$scope.persons = []

скорее всего будет быстрее.

Имейте в виду, что это запустит полный цикл дайджеста, инициируя каждый $watch и связанный атрибут, который вы определили как попадание.

person Abraham P    schedule 25.03.2014
comment
как показано здесь plnkr.co/edit/et9dxXR3cPUuthp7PxBN?p=preview, ваш подход должен работать . Любые другие контроллеры/HTML, которые вы могли бы опубликовать? - person Abraham P; 26.03.2014