2013-06-23 69 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

相关问题