2016-07-21 6 views
0

配列に項目を追加したり削除したりするためのドライ関数を作成しようとしています。編集可能なテーブルに役立ちます。これは、lodashの_.whithoutを使ってオブジェクトと配列を関数に渡すことを必要とするので、テーブル(または一般的な配列)から行を削除する必要があるときはいつでも、削除するオブジェクトと削除する配列を渡すだけです。ng-repeatオブジェクトと配列を_.withoutを使って関数に渡す

機能の配列を定義する問題が

正常に動作します。オブジェクトが削除され、DOMが更新されます。配列をパラメータとして渡すことはできません。オブジェクトは削除されますが、DOMは更新されません。

仮説

角度は、配列のバインドを解除されています。


どのように配列パラメータを保持することができますか?

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) 
    }; 
}; 

答えて

0

これであるためには、 _.withoutを呼び出すときはlodash creates a new arrayとなります。

次に、渡された引数に影響を与えない関数のパラメータにコピーを割り当てます。ファンクションスコープ内のパラメータ参照を新しいコピー_.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.splice(...)

むしろよりArray.prototyp.splice.apply(array, ...)を使用する理由は、スプライス配列の代わりに拡散引数を受け入れることです。 .applyトリックを使用することで、代わりに配列を渡すことができます。

+0

バインディングを正しく維持するためには、バインドされた配列のすべてをスプライシングし、_.withoutの結果で埋めています。それは興味深い解決策です。私はLodashが新しい配列を返すことを忘れていました。 – davidcapatch

+0

@davidcapatch、正しい。キーは、渡された配列を変更する必要があることです(または既存の '$ scope.items'を既に' .removeItemDef'で動作していたコピーで上書きする必要があります)。 –

関連する問題