2013-05-07 46 views
0

我使用AngularJS,AngularUI的jQuery傳遞uiJq和jQuery的noUiSlider插件,但問題實際上是關於訪問方法。 html部分正確地呈現滑塊,並且我需要雙向綁定到滑塊的輸出值。我在控制器中嘗試了下面的JavaScript代碼和它們的變體失敗。AngularUi jQuery Passthrough - 調用方法來獲取插件值

看起來像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 
}); 

謝謝!

回答

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(); 
}; 
+0

感謝你爲這個和你的工作一切角有關。你是對的。使用現有組件很容易,但我會以角度方式編寫適當的滑塊指令(如果每個人都可以使用IE10,以便使用HTML5範圍......) – 2013-05-08 02:27:22

+0

有價值的答案:)。謝謝 ! – 2014-11-05 10:08:22

0

這是一個快速骯髒的指令,包裝JQuery UI滑塊。只需設置ngModel,就像您始終會進行雙向綁定一樣,並將min最大方向和動畫屬性添加到您的指令標記。

用法示例:

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