LoginSignup
1
2

More than 5 years have passed since last update.

AngularJSのselectが使いづらいのでちょっとだけ改良したやつ

Last updated at Posted at 2016-10-21

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

こんな感じ

スクリーンショット 2016-10-21 13.19.42.png

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

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2