AngularUi jQuery Passthrough - 调用方法来获取插件值

时间:2013-05-07 23:47:19

标签: javascript jquery angularjs slider angular-ui

我正在使用AngularJS,AngularUI的jQuery passthrough uiJq和jQuery的noUiSlider插件,但问题实际上是关于访问方法。 html部分正确呈现滑块,我需要双向绑定到滑块的输出值。我在控制器中尝试了以下javascript代码及其变体,但未成功。

似乎uiJq不适用于所有jQuery插件。我想知道noUiSlider是否不起作用,我需要编写一个自定义指令。我也不确定是否需要处理延期执行或需要uiRefresh来手动$watch

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
});

谢谢!

2 个答案:

答案 0 :(得分:3)

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

其次,DON&#T; T在您的控制器中使用jQuery。控制器触发ONCE,并在模板“渲染”之前触发。这意味着您在初始化(甚至存在)之前检索DOM值并且因为.noUiSlider()从未在DOM元素上运行而导致错误。

对于AngularJS,您必须认为异步。模板不断变化,更新和刷新,您必须牢记这一期望。

无论如何,长话短说,你最好使用幻灯片回调功能来更新模型,虽然这有点hackish如果你不介意让你的鼻子湿透,你可以尝试制作一个新的指令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(); 
};

答案 1 :(得分:0)

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

样本用法:

<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;
});