【问题标题】:Javascript splice removing wrong itemsJavascript拼接删除错误项目
【发布时间】:2015-01-03 04:16:58
【问题描述】:

我有以下对象数组。

[{"name":"Rain"},{"name":"Storm"},{"name":"Forest"}]

其中有索引[0, 1, 2]。 我正在尝试使用代码删除给定位置上的项目:

$scope.selectedSounds.splice(index, 1);      

但它以错误的方式删除项目,例如无法删除最后一个项目。如果我试图删除索引为 1 的项目,它会删除索引为 2 的项目..

请问有什么问题?

两种方法我都试过了:

$scope.removeSoundFromSelection = function(index) {
    try {
        // First
        $scope.selectedSounds.splice(index, 1);
        var indexNew = $scope.selectedSounds.indexOf(index);
        console.log(indexNew);
        if (indexNew > -1) {
            $scope.selectedSounds.splice(indexNew, 1);
        }

        // Second
        if ($scope.selectedSounds.hasOwnProperty(index)){
            delete $scope.selectedSounds[index];
        }

        //delete $scope.selectedSounds[index];
    } catch(e) {
        $scope.showAlert();
    }
};

添加模板:

<div class="list">
          <a class="item item-thumbnail-left"  ng-repeat="sound in selectedSounds">
              <img src="cover.jpg">
              <h2>{{sound.name}}</h2>
              <p>TEST</p>
              <div class="customDeleteBtnInList">
                  <button ng-click="removeSoundFromSelection({{$index}})" class="button button-icon icon ion-close-circled"></button>
              </div>
          </a>
      </div>

【问题讨论】:

  • 它不是删除错误的项目,它只是在目标项目被删除后移动项目。所以现在可以在索引 1 处找到索引 2 处的项目
  • 你能告诉我们更多代码吗?你如何找到索引,你是否在循环中调用 splice?
  • 我更新了我的问题。
  • 那些条件是什么if (indexNew &gt; -1) { 为什么需要它?你为什么要拼接它然后delete ing 呢?告诉我们你是如何传递索引的?如果您使用 ng-repeat 并传递 $index,您只需要 $scope.selectedSounds.splice(index, 1);
  • 角度 schmangular。 myArray.splice(0,1) 实际上删除最初位于索引 1 处的元素而不是最初位于索引 0 处的元素的底层纯 JavaScript 原因是什么?

标签: javascript arrays angularjs angularjs-scope angularjs-ng-repeat


【解决方案1】:

您正在 ng-repeat 表达式 removeSoundFromSelection({{$index}}) 内对 {{$index}} 使用插值。只需删除插值并仅使用$index,它将自动根据范围进行评估。你只需要$scope.selectedSounds.splice(index, 1)

理想情况下,使用插值应该会导致解析错误而不是这种行为(除非使用非常旧的角度版本,即

工作演示

angular.module('app', []).controller('ctrl', function($scope) {
  $scope.selectedSounds = [{
    "name": "Rain"
  }, {
    "name": "Storm"
  }, {
    "name": "Forest"
  }];

  $scope.removeSoundFromSelection = function(index) {

    $scope.selectedSounds.splice(index, 1);

  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
  <div class="list">
          <a class="item item-thumbnail-left"  ng-repeat="sound in selectedSounds">
              <img src="cover.jpg">
              <h2>{{sound.name}}</h2>
              <p>TEST</p>
              <div class="customDeleteBtnInList">
                  <button ng-click="removeSoundFromSelection($index)" class="button button-icon icon ion-close-circled">Remove</button>
              </div>
          </a>
      </div>
</div>

即使问题中的这个特定场景不使用ng-init,如果您也使用ng-init 初始化索引别名,也会发生删除错误项目的问题。只需将该场景也添加到此问题的任何未来访问的答案中。即示例:-

<a class="item item-thumbnail-left"  
    ng-repeat="sound in selectedSounds" ng-init="idx=$index">
   ....
    <button ng-click="removeSoundFromSelection(idx)"

这将最终删除错误的项目,因为在摘要周期中不会监视和更新 ng-init 的范围属性。因此,即使在拼接数组 ng-inited idx 后该项目从 DOM 中删除,仍将具有该项目的旧索引,而 $index 特殊属性将更新以反映实际索引。所以在这种情况下,也可以使用$index 来传递索引,而不是使用缓存的 ng-inited idx

【讨论】:

    【解决方案2】:

    您正在删除该索引处的项目两次

    曾经在这里:

    $scope.selectedSounds.splice(index, 1);
    

    曾经在这里:

    // Second
    if($scope.selectedSounds.hasOwnProperty(index)){
        delete $scope.selectedSounds[index];
    }
    

    只需删除第二部分就可以了,我看不出在第一行 splice 之后您可以尝试做什么。

    【讨论】:

      【解决方案3】:

      以下代码按预期工作,似乎是您想要实现的目标:

      var sounds = [{"name":"Rain"},{"name":"Storm"},{"name":"Forest"}];
      sounds.splice(1, 1);
      
      console.log(sounds);
      

      我的猜测是您(在某些时候)没有使用正确的索引。查看根据@Alex J 的回答创建该变量的代码

      【讨论】:

        【解决方案4】:

        如果您希望删除中间项目,则 index 应该等于 1。您所做的任何逻辑都可能给您错误的 index

        *编辑:看到你更新的代码后,看起来你在拼接两次。您是第一次在 try 语句中执行此操作,然后转到 if 语句,这也是正确的。如果您正在尝试编写一个函数来在给定索引处拼接出一个对象,您可以这样做:

        $scope.removeSoundFromSelection = function(index) {
          if($scope.selectedSounds[index]){
            $scope.selectedSounds.splice(index, 1);
          }
        }
        

        【讨论】:

        • 它不会删除索引为零的项目。
        • @redrom 你能告诉我们你的观点吗,你有一个 ng-repeat。你如何获得索引?
        【解决方案5】:
        var season = [{"name":"Rain"},{"name":"Storm"},{"name":"Forest"}];
        var seasoned= season.slice(0, 2); 
        console.log(seasoned); //it sliced rain and storm...
        

        【讨论】:

          猜你喜欢
          • 2019-10-05
          • 2012-07-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-31
          • 2021-06-14
          相关资源
          最近更新 更多