Dynamically update ion.rangeSlider ngModel in AngularJS directive

独自空忆成欢 提交于 2019-12-18 07:08:44

问题


I'm trying to update the value of an Ion.RangeSlider when its bound ng-model scope variable changes. The model updates when the Ion.RangeSlider is used, but not vice-versa. Other inputs with the same ng-model update when the model value changes, so this must be some special case.

Edit: Woo! Here's a snippet @lin :) Also jsfiddle.

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

app.controller('MainCtrl', function ($scope, $rootScope, $timeout) {
    
    $scope.someNumber = 10;
    
}).directive('ionRangeSlider', function ionRangeSlider() {
   return {
      restrict: 'A',
      scope: {
         rangeOptions: '=',
         model: '=ngModel'
      },
      link: function (scope, elem, attrs) {
         scope.$watch('model',function () {
            elem.ionRangeSlider(scope.rangeOptions);
         });
      }
   }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.10/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.1.2/ui-bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.1.6/js/ion.rangeSlider.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.1.6/css/ion.rangeSlider.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.1.6/css/ion.rangeSlider.skinFlat.min.css" />

<div ng-app="ngModelIonRangeSliderDemo">
    <div ng-controller="MainCtrl" class="wrapper">
       <h3>Text input updates slider, but not vice-versa.</h3>
       <input ion-range-slider ng-model="someNumber" range-options="{min: -100, max: 100, step: .001}">
       <br/>
       <input type="text" ng-model="someNumber" class="form-control">
    </div>
</div>

I have tried all kinds of suggestions in over ten somewhat-related stack overflow posts (which is how I have set up the current scope.$watch scheme on the ngModel), but none have worked. There aren't any errors in my console. What's wrong? Also, why doesn't it work without any mention of the model in my directive? Please let me know if there's anything important I have failed to include in this post.


回答1:


Just use slider.update() inside your directive and you will be fine:

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

app.controller('MainCtrl', function ($scope, $rootScope, $timeout) {

    $scope.someNumber = 15;
    $scope.apply = false;

}).directive('ionRangeSlider', function ionRangeSlider() {
   return {
      restrict: 'A',
      scope: {
         rangeOptions: '=',
         model: '=ngModel',
         apply: '=apply'
      },
      link: function (scope, elem, attrs) {
         elem.ionRangeSlider(scope.rangeOptions);
         scope.$watch('apply',function () {
          if (scope.apply) {
            scope.apply = false;
            var slider = elem.data("ionRangeSlider");            
            slider.update({
               from: scope.model
            });
          }
         });
      }
   }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.10/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.1.2/ui-bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.1.6/js/ion.rangeSlider.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.1.6/css/ion.rangeSlider.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.1.6/css/ion.rangeSlider.skinFlat.min.css" />

<div ng-app="myApp" ng-controller="MainCtrl" class="wrapper">
  <h3>Text input updates slider and vice-versa.</h3>
  <input ion-range-slider ng-model="someNumber" apply="apply" range-options="{min: -100, max: 100, step: .001}">
  <br/>
  <input type="text" ng-model="someNumber" class="form-control" ng-change="apply = true">
</div>



回答2:


Extra demo, how binding ion.rangeSlider to input works:

http://jsfiddle.net/IonDen/r5aox84v/

var $range = $(".js-range-slider"),
    $inputFrom = $(".js-input-from"),
    $inputTo = $(".js-input-to"),
    instance,
    min = 0,
    max = 1000,
    from = 0,
    to = 0;

$range.ionRangeSlider({
    type: "double",
    min: min,
    max: max,
    from: 200,
    to: 800,
    onStart: updateInputs,
    onChange: updateInputs
});
instance = $range.data("ionRangeSlider");

function updateInputs (data) {
    from = data.from;
    to = data.to;

    $inputFrom.prop("value", from);
    $inputTo.prop("value", to); 
}

$inputFrom.on("input", function () {
    var val = $(this).prop("value");

    // validate
    if (val < min) {
        val = min;
    } else if (val > to) {
        val = to;
    }

    instance.update({
        from: val
    });
});

$inputTo.on("input", function () {
    var val = $(this).prop("value");

    // validate
    if (val < from) {
        val = from;
    } else if (val > max) {
        val = max;
    }

    instance.update({
        to: val
    });
});


来源:https://stackoverflow.com/questions/42605685/dynamically-update-ion-rangeslider-ngmodel-in-angularjs-directive

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!