0

I'm using AngularJS, AngularUI's jQuery passthrough uiJq and jQuery's noUiSlider plugin, but the question is really about accessing a method. The html portion correctly renders a slider, and I need to 2-way bind to the slider's output value. I tried the below javascript code and variation of them in controller unsuccessfully.

Seems like uiJq doesn't work with all jQuery plugins. I'm wondering if noUiSlider is one that doesn't work and I need to write a custom directive. Also not sure if I need to deal with Deferred Execution or need uiRefresh to manually $watch things.

HTML

<div class="noUiSlider" id="abc" ui-jq="noUiSlider"
    ui-options="{range: [0, 100], start: 50, handles: 1}"></div>

JS

app.controller('MainCtrl', function ($scope) {
    $scope.selectionValue = $('#abc').noUiSlider().val();
    // error, seems to override whatever is in html
    $scope.selectionValue = $('#abc').val();
    // no error but no value is returned
});

Thanks!

4

2 回答 2

3

好的,所以你一次遇到了很多各种各样的问题,很难弄清楚从哪里开始。首先,请阅读:https ://github.com/angular/angular.js/wiki/Understanding-Directives

其次,不要在控制器中使用 jQuery。控制器触发一次,并在模板“渲染”之前触发。这意味着您在它们初始化(甚至存在)之前检索 DOM 值,并且您收到错误,因为.noUiSlider()从未在 DOM 元素上运行。

当谈到 AngularJS 时,你必须异步思考。模板不断变化、更新和刷新,您必须在编写代码时牢记这种期望。

无论如何,长话短说,你最好使用滑动回调函数来更新模型,虽然这有点骇人听闻,如果你不介意弄湿你的鼻子,你可以尝试完全制定一个新指令requires: 'ngModel'

ui-options="{range, [0,100], start: 50, handles: 1, slide: slideCallback }"
...
$scope.slideCallback = function() {
  $scope.myModel = $(this).val();

  // this tells angular to refresh since an async event occurred outside of angular
  $scope.$apply(); 
};
于 2013-05-08T01:46:49.030 回答
0

这是一个包装 JQuery UI Slider 的快速脏指令。只需像往常一样设置 ngModel 进行双向绑定,并将 min max 方向和动画属性添加到指令标签。

样品用法:

<div si-slider ng-model="TargetModel.SomeIntProperty" min="100" max="2000" orientation="horizontal" animate="true"></div>

和代码:

var directives = angular.module('si.directives', []);    
directives.directive('siSlider', function ($rootScope) {
    var directiveDefinitionObject = {
        restrict: 'EA',
        transclude: 'false',
        template: '<div class="slider"></div>',
        replace: true,
        scope: { Model:"=ngModel"},
        link: function (scope, element, attrs) {
            var change = function () {
                scope.Model = (element).slider("value");
                if (!$rootScope.$$phase) {
                    scope.$apply();
                }
            };
            element.slider({
                value: scope.Model,
                animate: attrs.animate,
                orientation: attrs.orientation,
                min: parseInt(attrs.min, 10),
                max: parseInt(attrs.max, 10),
                slide: change,
                change: change
            });
            scope.$watch('Model', function (value) {
                element.slider("value", value);
            });
        }
    };

    return directiveDefinitionObject;
});
于 2013-05-22T21:14:04.450 回答