简体   繁体   English

jQuery UI中的更改未反映在Angular模型上

[英]Changes in jQuery UI not reflected on Angular models

I have a form which is in a directive. 我有一个指令中的表格。 It contains 2 select dropdowns (jQuery styled) and one jQuery UI slider, so it's all consistently themed. 它包含2个选择下拉列表(jQuery样式)和一个jQuery UI滑块,所以它一直是主题。

Dropdown 1 is populated at spawn, as simple as they come. 下拉1填充在spawn中,就像它们来的一样简单。 Dropdown 2 gets populated when the value of Dropdown 1 changes. 当Dropdown 1的值发生变化时,Dropdown 2将被填充。 This happens because dropdown 1 has ng-change="refreshModels()" attached to it. 发生这种情况是因为下拉列表1附加了ng-change="refreshModels()" This works like a charm. 这就像一个魅力。

However, sliders are more problematic. 但是,滑块更成问题。 In order to get the value of the slider, I need to have a hidden input field which gets populated with $.val() on every change in the slider position. 为了获得滑块的值,我需要有一个隐藏的输入字段,在滑块位置的每次更改时都会填充$ .val()。 The value updates correctly, and even the change event fires (when I put onchange="console.log('I changed')" onto the hidden field, I get everything logged nicely). 值正确更新,甚至更改事件触发(当我将onchange="console.log('I changed')"放到隐藏字段上时,我可以很好地记录所有内容。

However, the ng-model attached to that very same hidden field never updates. 但是,附加到同一隐藏字段的ng模型永远不会更新。 Ng-change never triggers, unlike onchange. 与onchange不同,Ng-change永远不会触发。

So I asked around and tried doing this in the jQuery slider's slide handler: 所以我四处询问并尝试在jQuery滑块的滑块处理程序中执行此操作:

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

But no dice. 但没有骰子。 Nothing happens. 什么都没发生。 Trying to call a model which I know exists in that directive like so: 试图调用我知道的模型,如下所示:

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

yields undefined. 产量未定义。 Trying to access a model in the parent controller of the directive also yields undefined. 尝试访问指令的父控制器中的模型也会产生undefined。

Why is it so difficult to make Angular register changes made by means other than direct user input on the field? 为什么通过现场直接用户输入以外的方式进行Angular寄存器更改是如此困难? What am I doing wrong? 我究竟做错了什么?

PS I tried putting ng-mouseup onto the element that becomes the slider, and that calls the refresh method fine - but diregards the hidden fields. PS我尝试将ng-mouseup放到成为滑块的元素上,并且调用刷新方法很好 - 但是指向隐藏的字段。 To Angular, those are still undefined, even though realistically, they have values - the slider put them there. 对于Angular来说,这些仍然是未定义的,即使现实地说,它们也有值 - 滑块将它们放在那里。

PPS I also tried putting a $watch onto the model I expect to change after moving the slider, nothing. PPS我还尝试将一块$ watch放在我希望在移动滑块后改变的模型上,没有。 The model's value never changes, even if the field's val actually does. 模型的值永远不会改变,即使字段的val实际上也是如此。

PPPS I just found this sad state of affairs. PPPS我刚刚发现了这种悲惨的状况。 https://github.com/angular-ui/angular-ui/issues/252 If anyone has a workaround, I'd be much obliged. https://github.com/angular-ui/angular-ui/issues/252如果有人有解决方法,我会非常感激。

I recently wrote a custom directive for jqueryUiSlider. 我最近为jqueryUiSlider编写了一个自定义指令。

You can view it on GitHub ( https://github.com/jvandemo/CoconutJS/blob/master/src/jquery-ui/directives/ccnutJqueryUiSlider.js ) but I'll post it here for reference: 你可以在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);
                };

            }
        };
    }]);

Here, the ngModelController is used to 'bind' the value of the slider to the model assigned to the directive using ng-model="yourModelName" . 这里,ngModelController用于使用ng-model="yourModelName"将滑块的值“绑定”到分配给指令ng-model="yourModelName"

Usage is simple like this: 用法很简单:

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

This will create a slider and store the value in the model specified by ng-model . 这将创建一个滑块并将值存储在ng-model指定ng-model

When updating the model, the slider will also slide to the new value. 更新模型时,滑块也将滑动到新值。

You can read some extra documentation in the comments of the source code at https://github.com/jvandemo/CoconutJS/blob/master/src/jquery-ui/directives/ccnutJqueryUiSlider.js 您可以在源代码的注释中阅读一些额外的文档, 网址https://github.com/jvandemo/CoconutJS/blob/master/src/jquery-ui/directives/ccnutJqueryUiSlider.js

Hope that helps! 希望有所帮助!

Not sure if it's an unfortunate amount of code or not, but I'm inclined to think a decent option is to use a simple directive to create/hook-up the jQueryUI sliders. 不确定它是否是一个不幸的代码量,但我倾向于认为一个不错的选择是使用一个简单的指令来创建/连接jQueryUI滑块。 The simple directive cooked up below sets up a two-way binding between the 'value' attribute on the directive's scope and the 'value' attribute on the controller's scope. 下面简单的指令设置了指令范围的'value'属性和控制器范围的'value'属性之间的双向绑定。 The template for the directive is simply the div that gets turned into the slider during the directive's link function, which also sets up a listener for the 'slide' event and copies the value to the scope. 该指令的模板只是在指令的链接函数中转换为滑块的div,它还为“slide”事件设置了一个监听器,并将值复制到范围。 The $watch is also set up so that changes from the controller get pushed into the slider's state. 还设置了$ watch,以便控制器的更改进入滑块的状态。

You can view the following sample live via this JSBin (different from what I commented above): http://jsbin.com/ejojad/1/edit 您可以通过此JSBin查看以下示例(与我上面评论的不同): http//jsbin.com/ejojad/1/edit

HTML: 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: 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 角度js模型值的变化不会反映在ui中 - Angular js model value changes are not reflected in ui 淘汰赛中的数据阵列变化没有反映到UI? - Data array changes in knockout are not getting reflected to UI? 角度工厂变量更改未反映在控制器中 - Angular factory variable changes not reflected in controller 服务器端对模型的更改未反映在UI中-EmberJS - Server-side Changes to Model not Reflected in UI - EmberJS 为什么在指令的链接功能中对$ scope进行的更改未在UI上反映出来? - Why are changes done to $scope in directive's link function not reflected on UI? 视图中输入类型=“时间”的值更改未反映在“角度模型”中 - Changes in the value of input type=“time” in View is not reflected in Model of Angular Angular js范围变量(数组)更改未反映在ng-repeat中 - Angular js scope variable (array) changes not reflected in ng-repeat Laravel/FancyTree 中 Jquery 对 CSS 所做的更改仅反映在 function 的末尾 - Changes made by Jquery to CSS in Laravel/FancyTree is only reflected at the end of the function 使用javascript / jQuery设置文本输入值时未反映出更改 - Changes not reflected when setting text input value with javascript/jQuery 状态更改,但未反映在DOM中 - State Changes but not reflected in DOM
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM