0

Im trying to make a directive that wraps around select with a hard-coded list

var app = angular.module('dirApp',[]);

app.directive('dir', [function(){
  return{
            restrict: 'E',
            template: "<select ng-options='x for x in vm.arr'></select>",
            controllerAs: 'vm',
            link: function(scope) {
                scope.arr=["a", "b"];
            }
        };
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="dirApp">
<dir></dir>
  </div>

As you can see for some reason the list does not get populated with values. What am I doing wrong?

David says Reinstate Monica
  • 19,209
  • 22
  • 79
  • 122

2 Answers2

2

You have to put your data into your Controller, and add an ngModel to your template.

Directive

(function(){

  function dir() {
      return{
          restrict: 'E',
          template: "<select ng-model='vm.x' ng-options='x for x in vm.arr'></select>",
          controllerAs: 'vm',
          controller: function() {
            var vm = this;
            vm.arr = ["a", "b"];
            vm.x = vm.arr[0]
          }
        };
  }

angular
  .module('app')
  .directive('dir', dir);


})();
Paul Boutes
  • 3,285
  • 2
  • 19
  • 22
  • What does it need to be in a `controller` instead of link? Isnt the `scope` object in `link` essentially the same thing? – David says Reinstate Monica Aug 07 '15 at 15:20
  • the `link` function is normally used for registering DOM listeners as well as updating the DOM. The `controller` must be used when another directive needs to interact with this directive like `ngOptions` for example. Moreover, your variable is set with `this` in your example, not in the `$scope`. Here you use `this` instead of `scope`. For more information, a good post here [this vs scope](http://stackoverflow.com/questions/11605917/this-vs-scope-in-angularjs-controllers/14168699#14168699) – Paul Boutes Aug 07 '15 at 15:23
0

You forgot to specify ng-model="currentValue" in your select; without it the options will not initialize. Also, you may want to define the controller if you want to reference it with controllerAs:

controller: function () {
        this.arr = ["a", "b"];
    },

or you can put your array directly in the scope of your directive. Here's a little update for your directive:

myApp.directive('dir', function () {
return {
    restrict: 'E',
    template: "<select ng-model='crrValue' ng-options='x for x in vm.arr'></select><div ng-repeat='item in arr'>{{item}}</div>",
    controller: function () {
        this.arr = ["a", "b"];
    },
    controllerAs: 'vm',
    link: function (scope) {
        scope.arr = ["c", "d"]
    }
};
});

You will notice the difference between the div and the select.

Hope this helps anyone!

bosch
  • 1,089
  • 11
  • 16