我有一个指令中的表格。它包含2个选择下拉列表(jQuery样式)和一个jQuery UI滑块,因此它始终是主题。
下拉1在spawn中填充,就像它们来的一样简单。
当Dropdown 1的值发生变化时,Dropdown 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 :(得分: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
的源代码评论中阅读一些额外的文档希望有所帮助!
答案 1 :(得分:1)
不确定它是否是一个不幸的代码量,但我倾向于认为一个不错的选择是使用一个简单的指令来创建/连接jQueryUI滑块。下面简单的指令设置了指令范围的'value'属性和控制器范围的'value'属性之间的双向绑定。该指令的模板只是在指令的链接函数中转换为滑块的div,它还为“slide”事件设置了一个监听器,并将值复制到范围。还设置了$ 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);