【问题标题】:Removing ngRepeat item from $rootScope array doesn't instantly remove the item from html从 $rootScope 数组中删除 ngRepeat 项目不会立即从 html 中删除该项目
【发布时间】:2016-07-20 15:00:06
【问题描述】:

尝试使用 angular 从 ul 中删除 li,成功从数组中删除元素,但 angularJS 没有删除 li直到它悬停在该特定 li 上/采取了某些操作。代码如下:

app.js

myApp.run(function($rootScope, appAPIservice){ 
  appAPIservice.getInterests().success(function (response) {
    $rootScope.interests = [];
    if (response.data) {
      var interests = response.data;
      for (var i = 0; i < interests.length; i++) {
        $rootScope.interests.push(interests[i]));
      }
    }
  });
});

index.html

<ul ng-controller="interestsController">   
  <li ng-repeat="interest in interests">
    <a href="#{{interest.link}}">{{interest.parentName}} / {{interest.childName}}</a>
    <button ng-click="deleteInterest($index)"></button>
  </li>
</ul>

controllers.js:这里定义了deleteInterest

myApp.controller('interestsController', function($scope) {
  $scope.deleteInterest = function(arrayIndex) {
          $scope.interests.splice(arrayIndex, 1);
      });
  }
});

这会在页面加载时产生以下输出:

<ul class="ng-scope" ng-controller="interestsController">   
  <li class="ng-scope" ng-repeat="interest in interests">
    <a href="#/other-link class="ng-binding">Other Parent/Other Child</a>
    <button ng-click="deleteInterest($index)"><i class="icon-close"></i></button>
  </li>
</ul>

单击 deleteInterest() 按钮时出现问题。以下类被添加到列表项类中:ng-animate、ng-leave、ng-leave-active。不幸的是,列表项仍保留在列表中直到该项目悬停在上方。此时,列表项已成功从 DOM 中删除。

<li class="ng-scope ng-animate ng-leave ng-leave-active" ng-repeat="interest in interests">
  <a href="#/some-link" class="ng-binding">Some Parent / Some Child </a>
  <button ng-click="deleteInterest($index)"><i class="icon-close"></i></button>
</li>

我尝试将interestController.deleteInterest 的
$scope.interests.splice(arrayIndex, 1); 行包装为

$scope.$apply(function(){ 
  $scope.interests.splice(arrayIndex, 1);
}); 

但我收到一条错误消息,指出 $scope.$digest 已在进行中。

有没有办法强制 angularJS 删除所有 ng-leave 项目?

【问题讨论】:

  • 只是好奇,为什么要使用 rootscope?
  • 根据之前的评论,开始将api逻辑引入到interestsController控制器中。当您需要动画时,您看到的那些 css 类很有用。你的 css 是否实现了一些 css 动画?如果是,您需要担心这些 css 类,否则不要担心它们。
  • $scope.$apply 在这里没有意义,您在这里拥有的每一段代码都在角度摘要周期内。这就是您收到该错误的原因。停止使用 $rootScope 并将其放入您的控制器/$scope 中。您无需在此处在 $rootScope 上放置任何内容,也无需使用 $scope.$apply。
  • @DanPantry 我们使用 $rootScope 是因为我们在侧边栏中显示兴趣,同时还允许用户单击页面上的“标志”,将兴趣添加到侧边栏中的兴趣数组中。由于这些包含在 html 的不同部分中,有没有办法在不同的地方调用控制器,即。两个不同的 div 结构?截至目前,兴趣按钮标志使用了一个指令,所以我不知道如何调用其中的兴趣控制器......
  • “有没有办法在不同的地方调用控制器”——服务?

标签: javascript angularjs


【解决方案1】:

几个想法。而不是$scope.$apply,试试

$timeout(function(){ 
  $scope.interests.splice(arrayIndex, 1);
});

$timeout 将在必要时在内部触发摘要,但如果摘要已经在进行中,则不会抛出该错误。

或者,如何仅使用 CSS 隐藏 li 直到 angular 将其移除?

.ng-leave { display:none; }

【讨论】:

  • css 更改是我们如何构建事物结构的一个很好的解决方法,谢谢。我仍然想弄清楚为什么 Angular 在应用后不会自行删除它。我已经尝试过超时功能,但无济于事。
【解决方案2】:

我对 ng-repeat 也有类似的问题。 将项目数组长度设置为 0 后,我必须长时间延迟运行超时:

$timeout(function(){ 
  do_some_action
}, 2000);

即使 evalAsync 也不起作用:

$scope.$evalAsync(function () {
   do_some_action
});

另一种解决方法是根本不考虑旧项目:

var elems = angular.element(document.getElementsByClassName('repeated_items'));
_.each(elems, function (itm) {
   if (itm.$$hashKey) return true;
   do_some_action
});

【讨论】:

    猜你喜欢
    • 2021-10-19
    • 2021-10-03
    • 2014-09-21
    • 2014-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    • 1970-01-01
    相关资源
    最近更新 更多