0

I have a use case where I need the slider-directive to update configuration & model value dynamically through a controller. For this I am trying to a create a two way data binding. However, I am not able to find the right way to create two way data-binding in directive. Following is the code. Currently an slide event on slider triggers directive to update 'scope.model'. Though it doesn't respond to controller updates for 'scope.config' or 'scope.model':

.directive("slider", function() {
return {
    restrict: 'A',
    scope: {
        config: "=config",
        model: "=model",
        trigger: '=trigger'
    },
    link: function(scope, elem, attrs) {

     //Data Binding to be done here using $watch for scope.model

        $(elem).slider({
            range: "min",
            min: scope.config.min,
            max: scope.config.max,
            value: scope.model,
            step: scope.config.step,
            slide: function(event, ui) {
                scope.$apply(function() {
                    scope.model = ui.value;
                });
                console.log(scope.model);
                scope.$apply(scope.trigger);
            }
            });
        }
    }
});

Please help me in this. I have gone through all the available answers but wasn't able to find the suitable answer

2

2 Answers 2

1

Base your directive on ngModelController. In this way you can use the ngModel functionality to bind everything, and use ngChange to run callback, without the need for $watch (plunkr):

app.directive("slider", function() {
  return {
    restrict: 'A',
    scope: {
      config: "=config"
    },
    require: 'ngModel',
    link: function(scope, elem, attrs, ngModel) {
      var init = false;
      var $slider = $(elem);

      ngModel.$render = function() {
        if (!init) {
          $slider.slider({
            range: "min",
            min: scope.config.min,
            max: scope.config.max,
            step: scope.config.step,
            slide: function(event, ui) {
              scope.$apply(function() {
                ngModel.$setViewValue(ui.value);
              });
            }
          });

          init = true;
        }

        $slider.slider('value', parseInt(ngModel.$viewValue, 10));
      }

    }
  }
});

Usage:

  <div id="km-slider" class="slider" slider="" config="milesSliderConfig" 
  ng-change="filterCars(sliderRanges.kms)"
  ng-model="sliderRanges.kms"></div>
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Ori. This is exactly the solution I was looking for. BTW can you give me a broad idea how can we extend it to Range Slider. I will take it up from there
Use the Jquery UI slider range option. The model should be an array [ 75, 300 ], and whenever a value is updated, you have to replace the array (to trigger model change), and not just the value.
0

I have figured out the solution to this by using $watch

//watch the Model to set slider when val in Model var changes
scope.$watch('model', function(newVal, oldVal){
   //check when Model is not initialized
   if (newVal !== undefined){
      elem.slider("value", parseInt(newVal,10));
       }
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.