3

I have a directive on a element called on-change. The idea is when the selected value changes it gets saved in a scope variable and then another element picks it up.

My problem is if the elements of the are static the above works fine but if I use ng-repeat, the onchange stops working.

<select on-change="myvar" ng-repeat="(key, value) in dataset">
   <option value="{{key}}">{{value.name}}</option>
</select>

here's my onchange directive:

.directive('onChange', function() {    
        return {
            restrict: 'A',
            scope:{'onChange':'=' },
            link: function(scope, elm, attrs) {            
                scope.$watch('onChange', function(nVal) { elm.val(nVal); });            
                elm.bind('blur', function() {
                    var currentValue = elm.val();                
                    if( scope.onChange !== currentValue ) {
                        scope.$apply(function() {
                            scope.onChange = currentValue;
                        });
                    }
                });
            }
        };        
    })

Any idea's on how I can overcome this issue?

Thanks

Sean D
  • 356
  • 5
  • 20
  • 4
    Why don't you use [ng-change](https://docs.angularjs.org/api/ng/directive/ngChange)? – Puigcerber Apr 17 '15 at 17:15
  • Also, was your goal to make multiple dropdowns for each (key,value) pair with a single option in it? That's what this HTML would do – brettvd Apr 17 '15 at 17:26
  • 1
    Is there a reason you need it set up like this? It seems like a simple `ng-model`, possibly with a `$watch` on that value, would make this much simpler – brettvd Apr 17 '15 at 17:28
  • so the reason why I didn't use ng-change is because ng-change doesn't fire if you change the value programically. – Sean D Apr 17 '15 at 17:38
  • I'm pretty sure your issue can be overcome if you used `ng-change` and *should* use `ng-change`. I suggest you add a fiddle of the case that's not working with the `ng-change` and we'll help you with that, right now it's just [the XY problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) – Omri Aharon Apr 19 '15 at 12:51

2 Answers2

0

What you can do is utilize ng-model and $watch in order to catch any changes. In order to reuse it, you can actually modify your code slightly to $watch ngModel.

(I'm just guessing you meant to make a single select with multiple options, not multiple selects with a single option, so I'm changing this accordingly)

<select ng-model="myvar" on-change>
   <option ng-repeat="(key, value) in dataset" value="{{key}}">{{value.name}}</option>
</select>

New link function:

link: function(scope, elm, attrs) {            
    scope.$watch(attrs.ngModel, function (newVal, oldVal) {
        if(newVal !== oldVal) {
            //Change happened, react accordingly
        }
    });
}

See my similar answer here

Community
  • 1
  • 1
brettvd
  • 486
  • 2
  • 5
0

I suggest you use ngOptions. In your case it should look something like:

<select ng-model="myVar" ng-options="key as value.name for (key, value) in dataset"></select>

And as some people suggested before me, use $watch to monitor changes in the model.

$scope.$watch('myVar', function(newValue, oldValue) {
   //whatever
});

See a simple example here.

Yaron Schwimmer
  • 5,327
  • 5
  • 36
  • 59