Может быть, кто-то может мне помочь. Я совершенно потерян с этим.

Я использую ng-repeat в приложении Angular, чтобы показать последние сообщения, отправленные пользователю, которые хранятся в массиве (lastQueries) внутри именованного контроллера, называемого «comunicacion»:

ng-repeat в comunicacion.html

<div class="list-group">
    <a class="list-group-item" ng-repeat="query in comunicacion.lastQueries | orderBy : 'last' : true  track by query._id ">
     {{query.subject}}
    </a>
</div>

Когда контроллер обнаруживает, что последние сообщения (запросы) были изменены, он снова извлекает их из базы данных с помощью этой функции:

comunicacion.js (контроллер)

 var self = this;
 self.getLastQueries = function(){
     $http.get( API + '/com/lastQueries/' + email ).then(
            function(res) {
                      self.lastQueries = res.data ? res.data.lastQueries : [];
     });
 };

И все работает отлично, как и должно быть. Но...

Проблема

Я использую ui-router для организации своих маршрутов (состояний). Например, я определяю это состояние "общение" следующим образом:

.state('comunicacion', {
                url:"/comunicacion",
                templateUrl: "views/comunicacion/comunicacion.html",
                controller: 'ComunicacionCtrl',
                controllerAs: 'comunicacion'
            })

Когда я перехожу в другие состояния и затем возвращаюсь "comunicacion", новые изменения в массиве "lastQueries" больше не отображаются в ng-repeat.

Однако изменения находятся в области $. Фаза $ scope. $$ - это $ digest, когда я изменяю массив.

Что я пробовал

  • $scope.$apply изменение, когда я получил массив из базы данных

  • $scope.$apply после изменения

  • $scope.$evalAsync вместо $apply

  • Не меняйте массив на новый, вместо этого делайте толчок новых элементов

Я не знаю, что я делаю не так, тем более что все идет хорошо, когда я не меняю состояние. Я действительно не знаю, имеет ли ui-router какое-то отношение к этому.

Извините за длинный вопрос, я старался быть максимально конкретным. Извините, мой плохой английский тоже, это не мой родной язык.

Код упрощен, чтобы показать только части, относящиеся к вопросу.

Спасибо.

0
Luisma 16 Дек 2015 в 18:08

4 ответа

Лучший ответ

Я наконец-то решил это. Я опубликую здесь решение, которое я нашел, в случае, если это может помочь кому-то еще:

Проверяя кое-что, я пришел к выводу, что у меня проблема с $ scope. ng-repeat создает свою собственную область, дочернюю для области контроллера ,

Итак, я сделал следующее:

Вместо объявления функции в контроллере следующим образом:

 var self = this;

 self.getLastQueries = function(){
 $http.get( API + '/com/lastQueries/' + email ).then(
        function(res) {
                  self.lastQueries = res.data ? res.data.lastQueries : [];
 });
};

Я использовал $ rootScope :

 $rootScope.lastQueries = = function(){
 $http.get( API + '/com/lastQueries/' + email ).then(
        function(res) {
                  $rootScope.lastQueries = res.data ? res.data.lastQueries : [];
 });
};

И инициализировал lastQueries каждый раз при создании экземпляра контроллера:

$rootScope.lastQueries = [];

Так что в html ng-repeat выглядит так:

<div class="list-group">
  <a class="list-group-item" ng-repeat="query in lastQueries | orderBy : 'last' : true  track by query._id ">
   {{query.subject}}
  </a>
</div>

Возможно, использование $ rootScope не самый элегантный способ, но он решил мою проблему! Я надеюсь, что это может помочь кому-то еще.

Спасибо всем за помощь!

0
Luisma 19 Фев 2016 в 09:13

Когда вы вернетесь к представлению comunicacion, вам нужно указать ui-router, что вы хотите перезагрузить контроллер.

<a ui-sref="comunicacion" ui-sref-opts="{reload: true}">Comunicacion</a>

Или в контроллере или директиве

$state.go('comunicacion', {}, {reload: true});

Другая возможность - вернуть lastQueries прямо из вашего метода:

//cominicacion.html
<div class="list-group">
    <a class="list-group-item" ng-repeat="query in comunicacion.lastQueries() | orderBy : 'last' : true  track by query._id ">
     {{query.subject}}
    </a>
</div>

//comunication.controller.js
var self = this;
 self.getLastQueries = function(){
     return $http.get( API + '/com/lastQueries/' + email ).then(
            function(res) {
                      return res.data.lastQueries; // This should be enough as this is the success callback ;-)
     });
 };

Может быть проблема в кеше? Не только браузер и англ, но и сервер тоже. Попробуйте добавить уникальный запрос в ваш запрос, чтобы вы были на 100% уверены в получении свежих данных ...

return $http.get( API + '/com/lastQueries/' + email , {
  cache: false,
  params: {
    avoidCache: Date.now().toString(16)
  }
})

Это может принадлежать $ http-перехватчику

0
Raulucco 16 Дек 2015 в 17:40

Может быть, это проблема с кешем. Попробуйте отключить кеш:

$http.get( API + '/com/lastQueries/' + email, {cache: false}).then(
        function(res) {
                  self.lastQueries = res.data ? res.data.lastQueries : [];
 });

Если это работает, тогда создайте лучший механизм для управления кешем (не рекомендуется отключать кеш). Увидеть

https://docs.angularjs.org/api/ng/service/$cacheFactory

А также

https://docs.angularjs.org/api/ng/type/$cacheFactory.Cache

0
Alex Pollan 16 Дек 2015 в 16:22

Я думаю, что при загрузке вашей области изменение self не обновляет саму область. Попробуйте изменить self.lastQueries на прямое изменение области $ и посмотрите, решит ли это это. Я думаю, что так и будет.

0
itamar 16 Дек 2015 в 16:16