【问题标题】:Passing ng-repeat object and array to function using _.without使用 _.without 将 ng-repeat 对象和数组传递给函数
【发布时间】:2016-07-21 18:44:26
【问题描述】:

我正在尝试创建干函数来添加和删除数组中的项目。对于可编辑的表格很有用。这需要使用 lodash 的 _.whithout 将对象和数组传递给函数,这样每当需要从表(或一般的数组)中删除一行时,只需传递要删除的对象和要从中删除的数组。

问题

在函数中定义数组可以正常工作。对象被移除并更新 DOM。将数组作为参数传递不会。对象已移除,但 DOM 未更新。

假设

Angular 正在解除对数组的绑定。


知道如何保持数组参数绑定吗?

Here's the fiddle

代码如下:

HTML

<table ng-controller="Ctrl">
  <thead>
    <tr>
      <th>
        <input ng-model="newItem" type="number">
      </th>
      <th>
        <button type="button" ng-click="addItemDef(newItem)">Add - Array Defined</button>
      </th>
      <th>
        <button type="button" ng-click="addItemUndef(newItem, items)">Add - Array Undefined</button>
      </th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat="item in items">
      <td>{{item.value}}</td>
      <td>
        <button type="button" ng-click="removeItemDef(item)">Remove - Array Defined</button>
      </td>
      <td>
        <button type="button" ng-click="removeItemUndef(item, items)">Remove - Array Undefined</button>
      </td>
    </tr>
  </tbody>
</table>

Javascript

function Ctrl($scope) {
  $scope.items = [{
    value: 5
  }];

  $scope.addItemDef = function(item) {
    foo = {
        value: item
      }
      //console.log(foo)
    $scope.items.push(foo);
    console.log($scope.items)
  };
  $scope.addItemUndef = function(item, array) {
    thing = {
      value: item
    }
    array.push(thing);
    console.log($scope.items)
  };

  $scope.removeItemDef = function(obj) {
    console.log('Before')
    console.log($scope.items)
      //    var itemWithId = _.find($scope.items, function(item) {
      //      return item.value == obj.value;
      //    });
    $scope.items = _.without($scope.items, obj);
    console.log('After')
    console.log($scope.items)
  };
  //This is the function that does not work
  $scope.removeItemUndef = function(obj, array) {
    console.log('Before')
    console.log(array)
    console.log($scope.items)
      //    var itemWithId = _.find(array, function(item) {
      //      return item.value == obj.value;
      //    });
    array = _.without(array, obj);
    console.log('After')
    console.log(array)
    console.log($scope.items)
  };
};

【问题讨论】:

    标签: javascript arrays angularjs lodash


    【解决方案1】:

    这是因为lodash creates a new array 在调用_.without 时。

    接下来,将副本分配给函数的参数,该参数对传入的参数没有影响;您只需使用来自_.without 的新副本覆盖函数范围内的参数引用。

    // this can't work:
    $scope.removeItemUndef = function(obj, array) {
       console.log('Before', array, $scope.items);
       array = _.without(array, obj); // << overwriting reference with no effect
       console.log('After', array, $scope.items);
    };
    

    解决方案是保持传递的数组不变,并使用Array.splice修改该数组的内部。

    // this however will work:
    $scope.removeItemUndef = function(obj, array) {
       console.log('Before', array, $scope.items);
       var result = _.without(array, obj);
       // remove the current content, and replace with result's content:
       Array.prototype.splice.apply(array, [0, array.length].concat(result));
       console.log('After', array, $scope.items);
    };
    

    Updated jsfiddle

    使用 Array.prototyp.splice.apply(array, ...) 而不是 array.splice(...) 的原因是 splice 接受扩展参数而不是数组。通过使用.apply 技巧,我们可以传递一个数组。

    【讨论】:

    • 所以如果我理解正确,为了保持绑定,我们将所有内容从绑定数组中拼接出来,并用 _.without 的结果填充它。这是一个有趣的解决方案。我忘记了 Lodash 返回一个新数组。
    • @davidcapatch,正确。关键是您需要修改传入的数组(或用副本覆盖现有的$scope.items,该副本已经在您的.removeItemDef 中工作)。
    猜你喜欢
    • 2016-11-28
    • 1970-01-01
    • 1970-01-01
    • 2016-08-31
    • 1970-01-01
    • 2017-08-03
    • 2018-08-05
    • 1970-01-01
    • 2020-12-22
    相关资源
    最近更新 更多