AngularJSのselect(ngOptions)が使いづらいの図
単純なlabelとvalueのセレクトボックスを作るのに
<select ng-model="model" ng-options="option.value as option.label for option in options">
いちいちこんなの書くのもなぁ・・・
しかもoptions
の構造が複雑すぎりゅ〜
improved-selectディレクティブ
index.html
<div ng-controller="testCtrl as ctrl">
<div>model: {{ctrl.model}}</div>
<div>
<button type="button" ng-click="ctrl.change(null)">nullにする</button>
<button type="button" ng-click="ctrl.change(true)">trueにする</button>
<button type="button" ng-click="ctrl.change(false)">falseにする</button>
<button type="button" ng-click="ctrl.change('hoge')">hogeにする</button>
</div>
<improved-select options="ctrl.options" model="ctrl.model"></improved-select>
</div>
template.html
<select ng-model="innerModel" ng-options="o.value as o.label for o in innerOptions" ng-change="onChange()"></select>
js
app.controller('testCtrl', function() {
var ctrl = this;
// セレクトボックスのoptionsを(label: value)で作る
ctrl.options = {
'選択してください': null,
'tるえ': true,
'ふぁlせ': false,
'ほげ': 'hoge'
};
// セレクトボックスの初期値
ctrl.model = null;
// 親スコープ側からmodel値を変更するスイッチ
ctrl.change = function(value) {
ctrl.model = value;
};
});
app.directive('improvedSelect', function() {
return {
restrict: 'E',
scope: {
options: '<',
model: '='
},
templateUrl: 'template.html',
replace: true,
controller: 'improvedSelectCtrl'
};
});
app.controller('improvedSelectCtrl', function($scope) {
$scope.innerOptions = [];
Object.keys($scope.options).forEach(function(label) {
$scope.innerOptions.push({value: $scope.options[label], label: label});
});
// セレクトボックスで変更されたとき
$scope.onChange = function() {
$scope.model = $scope.innerModel;
};
// 親スコープ側からの変更監視
$scope.$watch(function() { return $scope.model; }, function(model) {
if (angular.isUndefined(model) || $scope.innerModel === model) return;
$scope.innerModel = $scope.innerOptions.find(function(option) {
return option.value == model;
}).value;
});
});
こんな感じ

improved-select
タグにclassとか指定すればそのままselectタグにも反映されますお