2013-06-23 136 views
0

我有一個表單在指令中。它包含2個選擇下拉菜單(jQuery風格)和一個jQuery UI滑塊,因此它始終是主題。jQuery UI中的更改沒有反映在角度模型上

下拉列表1在生成時填充,就像它們來的那麼簡單。 當Dropdown 1的值發生變化時,下拉2會被填充。發生這種情況是因爲下拉列表1已附加ng-change="refreshModels()"。這像一個魅力。

但是,滑塊更成問題。 爲了獲得滑塊的值,我需要一個隱藏的輸入字段,在滑塊位置的每次更改中都會使用$ .val()填充。該值正確更新,甚至更改事件觸發(當我將onchange="console.log('I changed')"放到隱藏字段上時,我將所有內容都記錄得很好)。

但是,附加到該相同隱藏字段的ng模型從不更新。不像onchange那樣,Ng-change從不觸發。

所以我asked around,並試圖在jQuery的滑塊的滑動處理這樣做:

angular.element($(this)).scope().$apply(); 

但沒有骰子。什麼都沒發生。試圖打電話給我所知道的模型,就像我知道的那樣:

angular.element($(this)).scope().model_that_definitely_exists; 

產量未定義。嘗試訪問指令父控制器中的模型也會產生未定義的問題。

爲什麼使用直接用戶在字段中輸入以外的方式進行Angular寄存器更改如此困難?我究竟做錯了什麼?

P.S.我試着把ng-mouseup放到成爲滑塊的元素上,並且調用了刷新方法 - 但是直接調用隱藏的字段。對於Angular來說,這些仍然是未定義的,即使在現實中,它們也有價值 - 滑塊將它們放在那裏。

P.P.S.我也嘗試將$ watch放到我希望在移動滑塊後改變的模型上,沒有任何東西。模型的值永遠不會改變,即使字段的val實際上也是如此。

P.P.P.S.我剛剛發現這種令人傷心的事態。 https://github.com/angular-ui/angular-ui/issues/252如果任何人有解決方法,我會非常感激。

+0

[使用jQuery設置輸入值後更新角度模型]的可能重複(http://stackoverflow.com/questions/17109850/update-angular-model-after-setting-input-value-with-jquery) – Stewie

+1

Don '不知道這個JSBin是否有幫助:http://jsbin.com/azasus/1/edit – imaginaryboy

回答

3

我最近寫了一jqueryUiSlider的自定義指令。

您可以查看它在GitHub(https://github.com/jvandemo/CoconutJS/blob/master/src/jquery-ui/directives/ccnutJqueryUiSlider.js),但我會在這裏張貼供參考:

angular.module('ccnut.jquery-ui.directives') 
    .directive('ccnutJqueryUiSlider', ['ccnut.config', 'logger', function (ccnutConfig, logger) { 
     return { 
      restrict: 'AC', 
      require: 'ngModel', 
      link: function (scope, iElement, iAttrs, ngModelController) { 

       if (!window.$ || !window.$.fn || !window.$.fn.datepicker) { 
        return logger.warn('ccnutJqueryUiSlider directive skipped: slider function from jQuery UI library not available'); 
       } 

       // Get options 
       var options = angular.extend({}, scope.$eval(iAttrs.ccnutJqueryUiSlider)); 

       // Initialize slider 
       iElement.slider(options); 

       // Update model on slide event 
       iElement.on('slide', function (event, ui) { 
        ngModelController.$setViewValue(ui.value); 
        scope.$apply(); 
       }); 

       // Update slider when view needs to be updated 
       ngModelController.$render = function() { 
        var value = (ngModelController.$viewValue || 0); 
        iElement.slider('value', value); 
       }; 

      } 
     }; 
    }]); 

這裏,ngModelController是用來「綁定」滑塊的分配給模型中的價值該指令使用ng-model="yourModelName"

用法很簡單這樣的:

<div ng-model="model" ccnut-jquery-ui-slider="{min:1, max:5}"></div> 

這將創建一個滑塊和值存儲在由ng-model指定的型號。

更新模型時,滑塊也會滑動到新值。

您可以在https://github.com/jvandemo/CoconutJS/blob/master/src/jquery-ui/directives/ccnutJqueryUiSlider.js

希望幫助閱讀源代碼的註釋一些額外的文檔!

+0

就像一個魅力,謝謝! – Swader

+0

你會如何將這個應用於範圍滑塊,因爲只有一個模型可以綁定到它?我嘗試過這種方式,但結果不如恆星:http://hastebin.com/qotafaduwi.html – Swader

+0

我刪除了ng模型和一些其他依賴項,並使它與範圍兼容。感謝您的正確方向! https://github.com/Swader/ngdirectives – Swader

1

不確定它是不是一個不幸的代碼量,但我傾向於認爲一個體面的選擇是使用一個簡單的指令來創建/連接jQueryUI滑塊。下面編寫的簡單指令在指令作用域的'value'屬性和控制器作用域的'value'屬性之間建立了雙向綁定。該指令的模板只是在指令鏈接函數期間變成滑塊的div,該函數還爲「幻燈片」事件設置偵聽器並將該值複製到作用域。 $ watch也被設置爲使得來自控制器的變化被推入滑塊的狀態。

您可以查看通過這個JSBin下面的示例住(從不同的就是我上面註釋):http://jsbin.com/ejojad/1/edit

HTML:

<!DOCTYPE html> 
<html> 
<head> 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script> 
    <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/smoothness/jquery-ui.min.css" rel="stylesheet" type="text/css" /> 
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> 
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script> 
    <meta charset=utf-8 /> 
    <title>JS Bin</title> 
</head> 
<body> 
    <div ng-app="myApp" ng-controller="Ctrl"> 
    <input type="text" ng-model="value"/> 
    <jqui-slider value="value"></jqui-slider> 
    </div> 
</body> 
</html> 

的JavaScript:

function Ctrl($scope) { 
    $scope.value = 0; 
} 

function jQuiSliderDirective() { 
    return { 
    restrict: 'E', 
    scope: { 
     value: '=value', 
    }, 
    template: '<div></div>', 
    replace: true, 
    link: function($scope, elem, attrs) { 
     var slider = $(elem).slider(); 
     slider.on('slide', function(event, ui) { 
     $scope.$apply(function() { 
      $scope.value = ui.value; 
     }); 
     }); 
     $scope.$watch('value', function(val, old) { 
     slider.slider('value', val); 
     }); 
    } 
    }; 
} 

var myApp = angular.module('myApp', []); 
myApp.directive('jquiSlider', jQuiSliderDirective); 
+0

由於某些原因,它從jQuery拋出了「method addClass not defined」錯誤。很好的例子,但是,謝謝 - 我從中學到了很多東西。 – Swader

相關問題