IgnorantUser
IgnorantUser

Reputation: 307

Issues with passing ng-model to custom directive and making it work

I've created a custom directive that auto-populates a select with a list of countries. The directive has a preselect isolate scope attribute, that if set to true will preselect a country.

ng-model is also passed as an isolate scope attribute The problem is that ng-model won't be set.

Could anyone give me some pointers on how to make the <auto-countries> directive so that I'm able to set ng-model ?

here's my directive's code:

app.directive('autoCountries', function() {
    return {
        restict: 'E',
        controller: 'CountriesCtrl as ctrl',
        scope: {
            preselect: '=',
            ngModel: '='
        },
        template: [

            '<select ng-if="!preselect" ng-model="ngModel">',
                '<option value="">Select Country</option>',
                '<option ng-repeat="country in ctrl.countries" value={{country.name}}>',
                    '{{country.name}}',
                '</option>',
            '</select>',

            '<select ng-if="preselect" ng-model="ngModel">',
                '<option ng-repeat="country in ctrl.countries" ng-selected="ctrl.countryFromIP == country.name" value={{country.name}}>',
                    '{{country.name}}',
                '</option>',
            '</select>',
        ].join('')
    }
})

What makes things more weird is that in a simpler version of the directive that doesn't use at all the preselect, the ng-model will be set.

It's kinda hard to understand without an example, so here's a Plunkr! http://plnkr.co/edit/e1HPgGQlne7Q4TcNJ9XT?p=preview

Upvotes: 1

Views: 326

Answers (2)

sombrerogalaxy
sombrerogalaxy

Reputation: 406

You should use ngOptions instead of ngRepeat. I forked dave's plnkr and adjusted it a bit. Your template with and without preselection will look like this:

'<select ng-model="ngModel" ng-options="country.name as country.name for country in ctrl.countries"></select>'

I did the pre-selection in the countries controller instead of the view/template, just like in angular's documentation for ngOptions.

$scope.ngModel = $scope.preselect ? $scope.ngModel = vm.countries[3].name : "";

(if preselect equals true then set default for ngModel, else set empty string - javascript ternary operator.)

Upvotes: 1

dave
dave

Reputation: 64657

You should never use ng-repeat on <option>, instead use ng-options on the <select>:

  <select ng-model="ngModel" ng-options="country.name as country.name for country in ctrl.countries"></select>

http://plnkr.co/edit/ADTPOIKZnnt14lVcr8TN?p=preview

Upvotes: 2

Related Questions