AngularJS ng repeat没有't在状态更改时更新

AngularJS ng-repeat doesn't update on state change

本文关键字:状态 更新 repeat ng 没有 AngularJS      更新时间:2023-09-26

也许有人能帮我。我很困惑。

我在Angular应用程序中使用ng repeat来显示发送给用户的最新消息,这些消息存储在一个名为"comunicacion"的命名控制器内的数组(lastQueries)中:

ng在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路由器来组织我的路由(状态)。例如,我将这种状态定义为"通信",如下所示:

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

当我导航到另一个状态,然后返回"comunicacion"时,数组上新的更改"lastQueries"将不再显示在ng repeat中

不过,这些更改在$范围内。$范围$$当我更改数组时,阶段是$digest。

我尝试过的东西

  • $scope.$apply当我从数据库获得阵列时的变化

  • 更改后的$scope.$apply

  • $scope.$evalAsync代替$apply

  • 不要为新的数组更改数组,而是推送新元素

我不知道自己做错了什么,尤其是因为当我不改变状态时,一切都会好起来。我真的不知道ui-router是否与此有关。

很抱歉问了这么长的问题,我尽量做到最具体。也请原谅我英语不好,这不是我的第一语言。

代码被简化为只显示与问题相关的部分。

谢谢。

我认为加载作用域的方式是使self的更改不更新作用域本身。尝试将self.lastQueries更改为$scope的直接更改,看看这是否能解决问题。我认为会的。

可能是缓存问题。尝试禁用缓存:

$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

返回comunicacion视图时,需要指定要重新加载控制器的ui路由器。

<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拦截器

我终于解决了这个问题。我会在这里发布我发现的解决方案,以防这可以帮助其他人:

在这里和那里测试,我得出的结论是,我有一个$范围的问题。ng重复创建他自己的作用域,即控制器作用域的子作用域。

所以我做了以下事情:

而不是像这样在控制器中声明函数:

 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重复如下所示:

<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不是最优雅的方式,但它解决了我的问题!我希望这能帮助其他人。

谢谢大家的帮助!