5

AngularJS v1.2.0-rc.3 を使用しています。

モデル x と 1 対多の関係を持つモデル y があります。

最初に、次のような xs の複数選択を持つモデル y のフォームがありました。

コントローラ:

function test($scope) {
  $scope.xs = [
    {id:1, value:'value 1'},
    {id:2, value:'value 2'},
    {id:3, value:'value 3'}
  ];
  $scope.y = {xs:[2]};
}

意見:

<div ng-controller="test">
  <select multiple ng-model="y.xs" ng-options="x.id as x.value for x in xs">
  </select>    
</div>

結果は、選択された項目の配列です。

http://plnkr.co/edit/s3tvvHeyE17TVH5KNkPZ

すべて問題ありませんが、チェックボックスリストに変更する必要があり、配列を使用できなくなったことがわかりました。

次のように、リピーターのインデックスを使用してみました。

<div ng-repeat="x in xs">
  <input type="checkbox" ng-model="y.xs[$index]" ng-true-value="{{x.id}}"/>
  {{x.value}}
</div>

しかし、たとえば2番目のアイテムを事前に選択するには、これを使用する必要がありました:

$scope.y = {xs: [null, '2']};

これは役に立たなかった。

http://plnkr.co/edit/9UfbKF2gFLnhTOKu3Yep

少し検索した後、推奨される方法はオブジェクトハッシュを使用することです。

<div ng-repeat="x in xs">
  <input type="checkbox" ng-model="y.xs[x.id]"/>
  {{x.value}}
</div>

http://plnkr.co/edit/Xek8alEJbwq3g0NAPMcF

ただし、アイテムの選択を解除すると、次のようになります。

y={
  "xs": {
    "1": false,
    "2": false,
    "3": false
  }
}

そのため、次のように、偽の値を除外するためのウォッチ式を追加することになりました。

$scope.$watch('y.xs', function(n) {
  for (var k in n) 
    if (n.hasOwnProperty(k) && !n[k]) 
      delete n[k];
}, true);

http://plnkr.co/edit/S1C1g5fYKzUZb7b0pRtp

動作しますが物足りない感じです。

これは非常に一般的な使用例であるため、他の人がどのように解決しているかを知りたいです。

アップデート

カスタム ディレクティブを使用するという提案に従って、選択をリストとして維持するこのソリューションを思いつきました。

指令:

angular.module('checkbox', [])
.directive('checkboxList', function () {
  return {
    restrict: 'A',
    replace: true,
    scope: {
      selection: '=',
      items: '=',
      value: '@',
      label: '@'
    },
    template: '<div ng-repeat="item in list">' +
      '<label>' +
      '<input type="checkbox" value="{{item.value}}" ng-checked="item.checked" ng-click="toggle($index)"/>' +
      '{{item.label}}' +
      '</label>' +
      '</div>',
    controller: ['$scope', function ($scope) {
      $scope.toggle = function (index) {
        var item = $scope.list[index],
          i = $scope.selection.indexOf(item.value);
        item.checked = !item.checked;
        if (!item.checked && i > -1) {
          $scope.selection.splice(i, 1);
        } else if (item.checked && i < 0) {
          $scope.selection.push(item.value);
        }
      };
      $scope.$watch('items', function (value) {
        $scope.list = [];
        if (angular.isArray(value)) {
          angular.forEach(value, function (item) {
            $scope.list.push({
              value: item[$scope.value],
              label: item[$scope.label],
              checked: $scope.selection.indexOf(item[$scope.value]) > -1
            });
          });
        }
      }, true);
    }]
  };
});

意見:

<div checkbox-list
     selection="a.bs"
     items="bs"
     value="id"
     label="name">
</div>

http://plnkr.co/edit/m7yH9bMPuRCg5OP2u0VX

4

3 に答える 3

2

過去に自分で複数選択ディレクティブを作成する必要がありました。 http://isteven.github.io/angular-multi-selectで自由に入手してください。

データ バインディングのアプローチに関しては、私のデータ構造は実際にはあなたのものと非常に似ていますが、私のアプローチでは、チェックボックスの状態を表すプロパティをもう 1 つ追加しました。

例、上記の入力で、「チェック済み」を追加しました。

$scope.xs = [
    { id:1, value:'value 1', checked: false },
    { id:2, value:'value 2', checked: false },
    { id:3, value:'value 3', checked: false }
];

そして、次のようにディレクティブに渡します。

<div 
    multi-select 
    input-model="xs" 
    button-label="value" 
    item-label="id value" 
    tick-property="checked" >
</div>

チェックボックスをオンまたはオフにすると、ディレクティブはそれに応じて入力モデル $scope.xs.checked を変更します。これを実現するために、各チェックボックスにクリック ハンドラーを追加します。このハンドラーは、関数パラメーターとしてチェックボックス オブジェクトを渡す関数を呼び出します。この関数は、チェックボックスの状態とモデルを同期します。

選択された/チェックされたチェックボックスを取得するには、$scope.xsどこをループするだけで済みます.checked === true

例:

angular.forEach( $scope.xs, function( value, key ) {
    if ( value.checked === true ) {
         // Do your stuff here
    }
});

私の悪い英語を許してください。これが役に立てば幸いです。乾杯。

于 2014-04-30T02:07:47.630 に答える
1

私は直接的なアプローチに行きました。チェックされたオブジェクトの ID のリストが表示されます。これはJSFIDDLEのフィドルです。これは私のhtmlがどのように見えるかです。

<div ng-app="checkbox" ng-controller="homeCtrl">
    <div ng-repeat="item in list">
        <input type="checkbox" checkbox-group />
        <label>{{item.value}}</label>
    </div>{{array}}
    <br>{{update()}}
</div>

そして私の指令

.directive("checkboxGroup", function () {
    return {
        restrict: "A",
        link: function (scope, elem, attrs) {
            // Determine initial checked boxes
            if (scope.array.indexOf(scope.item.id) !== -1) {
                elem[0].checked = true;
            }

            // Update array on click
            elem.bind('click', function () {
                var index = scope.array.indexOf(scope.item.id);
                // Add if checked
                if (elem[0].checked) {
                    if (index === -1) scope.array.push(scope.item.id);
                }
                // Remove if unchecked
                else {
                    if (index !== -1) scope.array.splice(index, 1);
                }
                // Sort and update DOM display
                scope.$apply(scope.array.sort(function (a, b) {
                    return a - b
                }));
            });
        }
    }
});
于 2013-11-08T22:33:32.583 に答える