あなたが提供するサンプルソリューションは、コントローラーにあまりにも多くのコードを入れていると思います。コントローラは実際にはリストのみを気にする必要があり、HTML /ディレクティブが表示を処理する必要があります([すべて選択]チェックボックスの表示を含む)。また、すべての状態の変化は、関数を作成することではなく、モデルを介して行われます。
Plunkerでソリューションをまとめました:http://plnkr.co/edit/gSeQL6XPaMsNSnlXwgHt?p = Preview
これで、コントローラーはリストを設定するだけです。
app.controller('MainCtrl', function($scope) {
$scope.list = [{
isSelected: true,
desc: "Donkey"
}, {
isSelected: false,
desc: "Horse"
}];
});
ビューは単にそれらをレンダリングします:
<div ng-repeat="elem in list">
<input type="checkbox" ng-model="elem.isSelected" /> {{elem.desc}}
</div>
[すべて選択]チェックボックス用に、次のような新しいディレクティブを作成しましたcheckbox-all
。
<input checkbox-all="list.isSelected" /> Select All
そして、それは使用に関する限りそれです、それはうまくいけば簡単です...その新しいディレクティブを書くことを除いて:
app.directive('checkboxAll', function () {
return function(scope, iElement, iAttrs) {
var parts = iAttrs.checkboxAll.split('.');
iElement.attr('type','checkbox');
iElement.bind('change', function (evt) {
scope.$apply(function () {
var setValue = iElement.prop('checked');
angular.forEach(scope.$eval(parts[0]), function (v) {
v[parts[1]] = setValue;
});
});
});
scope.$watch(parts[0], function (newVal) {
var hasTrue, hasFalse;
angular.forEach(newVal, function (v) {
if (v[parts[1]]) {
hasTrue = true;
} else {
hasFalse = true;
}
});
if (hasTrue && hasFalse) {
iElement.attr('checked', false);
iElement.addClass('greyed');
} else {
iElement.attr('checked', hasTrue);
iElement.removeClass('greyed');
}
}, true);
};
});
変数はを2つの部分にparts
分解するので、スコープからlist.isSelected
値を取得できます。これは、各オブジェクトのプロパティです。list
isSelected
プロパティをinput要素に追加しtype="checkbox"
て、ブラウザの実際のチェックボックスにします。つまり、ユーザーはそれをクリックしたり、タブで移動したりできます。
チェックボックスはキーボードを介するなど、さまざまな方法で変更できるため、私はonchange
イベントではなくイベントにバインドします。onclick
onchangeイベントは、の内部で実行scope.$apply()
され、モデルの変更が最後にダイジェストされるようにします。
最後に$watch
、チェックボックスを変更するための入力モデルを入力します(最後のモデルでは、true
複雑なオブジェクトを監視できます)。つまり、チェックボックスがユーザーによって、またはその他の理由で変更された場合、[すべて選択]チェックボックスは常に同期されます。これは、ng-clickハンドラーをたくさん書くよりもはるかに優れています。
チェックボックスがオンとオフの両方の場合、マスターチェックボックスをオフに設定し、スタイル「灰色」を追加します(を参照style.css
)。そのCSSスタイルは基本的に不透明度を30%に設定し、チェックボックスを灰色で表示しますが、それでもクリック可能です。タブで移動し、スペースバーを使用して値を変更することもできます。
Firefox、Chrome、Safariでテストしましたが、IEを持っていません。うまくいけば、これはあなたのために働きます。