【问题标题】:Convert jQuery UI slider widget to AngularJS directive将 jQuery UI 滑块小部件转换为 AngularJS 指令
【发布时间】:2014-08-28 13:43:52
【问题描述】:

我正在尝试构建一个 Angular 指令来创建一个键盘可访问的滑块小部件。我在 Github 上找到了几个 Angular 滑块,但没有一个可以通过键盘访问。所以,我正在尝试将 jQuery UI 滑块转换为 Angular 指令。

这是我在没有 Angular 的情况下构建小部件的方法。

HTML:

<div id="slider"></slider>
<input type="text" id="amount"/>

Javascript:

$("#slider").slider({
  min: 1,
  max: 10,
  slide: function(event, ui) {
    $("#amount").val(ui.value);
  }
});

这就是我希望 Angular 指令的工作方式:

<slider min="1" max="10" ng-model="sliderValue"/>
<input type="text" ng-model="sliderValue"/>

作为一个例子,这里有一个 jsFiddle,它展示了某人如何将 jQuery UI 日期小部件转换为 Angular 指令。

http://jsfiddle.net/xB6c2/121/

我想为滑块小部件做类似的事情。谢谢!

【问题讨论】:

    标签: jquery angularjs jquery-ui angularjs-directive jquery-ui-slider


    【解决方案1】:

    这是一个有效的解决方案。感谢 Duc Hong - 他的回答有助于我解决这个问题。如果有更好的方法,请告诉我。

    app.directive('slider', function() {
        return {
            restrict: 'AE',
            link: function(scope, element, attrs) {
                element.slider({
                    value: scope[attrs.ngModel],
                    min: parseInt(attrs.min),
                    max: parseInt(attrs.max),
                    step: parseFloat(attrs.step),
                    slide: function(event, ui) {
                        scope.$apply(function() {
                            scope[attrs.ngModel] = ui.value;
                        });
                    }
                });
            }
        };
    });
    

    【讨论】:

    • 谢谢,很有帮助。对我来说,唯一的区别是 value: scope[attrs.ngModel].price,scope[attrs.ngModel].price= ui.value; 两行,是在 ng-repeat 中使用的。
    • 我不得不稍微修改这个指令,因为我在尝试拖动滑块时收到一条错误消息,提示“未捕获的类型错误:无法读取未定义的属性 'addClass'”。原来这是因为我使用“getterSetter”函数作为模型。我在这个要点中添加了对 getterSetter 函数的支持:gist.github.com/NoxHarmonium/d53d07bda7417d6d8004 如果有人知道更好的方法,请告诉我它似乎有点笨拙。此外,除非我使用滑块关键字作为属性 (
      ) 语法而不是
      ,否则我似乎无法让它工作
    【解决方案2】:

    您可以为您的 UI 滑块编写指令,它的工作原理如下:

    <input type="text" ng-model="setMin" />
    <input type="text" ng-model="setMax" />
    <slider min="setMin" max="setMax"></slider>
    

    你的指令会是这样的:

    app.directive("slider", function() {
        return {
            restrict: "AE",
            scope:{
               min:"=",
               max:"="
            },
            link: function(scope, ele, attrs) {
    
                ele.slider({
                    min: scope.min,
                    max: scope.max,
                    range: "min",
                    value: "5",
                    slide: function(event, ui) {
                        scope.$apply(function() {
                            //update on the view using ui.value;
                            //scope.number =  = ui.value;
                        });
                    }
                });
    
               // You can watch the value min,max and then reapply your UI slider 
                scope.$watch('setMin', function(newValue, oldValue) {
                    if (newValue !== null && newValue !== undefined) {
                       // re-apply UI slider
                    }
                }, true);
    
                scope.$watch('setMax', function(newValue, oldValue) {
                    if (newValue !== null && newValue !== undefined) {
                       // re-apply UI slider
                    }
                }, true);
    
            }
        }
    });
    

    希望你能明白,干杯

    【讨论】:

      【解决方案3】:

      对 Rodney 解决方案的小改进:

      app.directive('slider', function() {
          return {
              restrict: 'AE',
              link: function(scope, element, attrs) {
                  element.slider({
                      value: scope[attrs.ngModel],
                      min: parseInt(attrs.min),
                      max: parseInt(attrs.max),
                      step: parseFloat(attrs.step),
                      slide: function(event, ui) {                    
                          scope.$apply(function() {           
                              scope[attrs.ngModel] = ui.value;
                          });
                      }
                  });
      
                  scope.$watch(attrs.ngModel, function(newVal, oldVal){
                      element.slider({value: newVal});
                  });
              }      
          };
      });
      

      如果模型发生变化,它允许检测和更新滑块位置。

      如果您的模型包含点(例如,ngmodel = "Configuration.Size"),scope[attrs.ngModel] 将不再有效。一种解决方法是改用 lodash 库中的 _.get_.set

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-29
        • 1970-01-01
        • 2016-07-14
        • 1970-01-01
        • 2020-09-18
        • 1970-01-01
        • 2021-07-17
        相关资源
        最近更新 更多