【问题标题】:How to change complicated function to angular directive如何将复杂功能更改为角度指令
【发布时间】:2014-06-07 17:12:33
【问题描述】:

我有一个辅助函数,用于将输入与 jQuery 自动完成绑定,并带有一组额外的选项,例如在悬停时显示引导弹出窗口、使用辅助标签的能力等... 我面临一个问题,即从自动完成列表中选择项目时我的 ngModel 没有更新。此自动完成选择将更新文本字段(用于显示值)和隐藏字段(用于值)。我想将其更改为指令并在所选项目的文本和值字段中通知 ngModel。

bindAutocomplete: function (textSelector, valSelector, serviceUrl,
    secondaryLabel, minLength, selectCallback,
    tooltipPlacement, showOnTopOfField) {

    if (!tooltipPlacement) {
        tooltipPlacement = "right";
    }

    var autoCOmpletePosition = { my: "left bottom", at: "left top", collision: "flip" };
    if (!showOnTopOfField || showOnTopOfField == false) {
        var autoCOmpletePosition = { my: "left top", at: "left bottom", collision: "none" };
    }

    if (!minLength)
        minLength = 2;

    var jTextSelector = $(textSelector),
        jValSelector = $(valSelector),
        jTextSelectorId = jTextSelector.attr("id");

    jTextSelector.autocomplete({
        source: serviceUrl,
        minLength: minLength,
        position: autoCOmpletePosition,
        select: function (event, ui) {

            jValSelector.val(ui.item.id);

            if (selectCallback) {
                selectCallback(event, ui);
            }
        },
        response: function (event, ui) {
            jQuery.data(jTextSelector[0], jTextSelectorId, ui.content); // Store Filtered result in jQuery data store
        }
    });

    if (secondaryLabel) {

        var uiAutoCompleteData = jTextSelector.data("ui-autocomplete");
        if (uiAutoCompleteData) {
            uiAutoCompleteData._renderItem = function (ul, item) {
                return $("<li>")
                  .append("<a><b>" + item.label + "</b><br><span style='font-size:0.8em;'>" + item.desc + "</span></a>")
                  .appendTo(ul);
            };
        }
    }

    jTextSelector.hover(function () { // On Hover
        bindPopOver(this);
        jTextSelector.popover('show');
    },
    function () { // On Unhover
        jTextSelector.popover('destroy');
    });
    function bindPopOver(element) {
        if (!$(element).val()) {
            jValSelector.val("");
            jTextSelector.popover('destroy');
        }
        else {

            var listContent = jQuery.data(jTextSelector[0], jTextSelectorId); // Get Filtered result from jQuery data store
            var text = jTextSelector.val();

            var item = _.find(listContent, function (itemInList) {
                return itemInList.label.toLowerCase() == text.toLowerCase();
            });

            if (item) {
                jValSelector.val(item.id);
                jTextSelector.popover('destroy');
                jTextSelector.popover({
                    title: text,
                    trigger: 'hover',
                    content: item.desc,
                    placement: tooltipPlacement
                });
            }
            else if (!item && text == "") {
                jValSelector.val("");
                jTextSelector.popover('destroy');
            }
        }
    };
},

【问题讨论】:

    标签: javascript jquery angularjs jquery-ui twitter-bootstrap


    【解决方案1】:

    您可以使用指令技术在 DOM 组件和 angularjs 之间传输数据。

    我创建了一个简单的代码来帮助我们进行绑定。

    plunker

    主要规则是指令的“链接”,辅以“范围”定义以反映外部数据:

    scope: { ngMyModel: '=' }
    
    link: function(scope, el, attrs) {
        scope.$watch('ngMyModel', function (val) {
          el.val(val);
        });
        el.on('change input', function() {
          scope.$apply(function(scope) {
              scope.ngMyModel = el.val();
          });
        });
    }
    

    在第一部分我反映了输入(或其他组件,如 datepicker 等)对 angularjs 数据的任何更改。

    在第二部分,我从元素中捕获事件并使用“scope.$apply”技术来反映 angularjs 数据。

    【讨论】:

    • 是的,没错,我现在可以像您在 ng-my-model 中所做的那样传递任何额外的参数...。谢谢您的回答。
    • 不客气!此外,您可以使用 "ngAnotherAttribute": "@" 表示字符串非变量参数,如掩码或标题。
    猜你喜欢
    • 2015-08-26
    • 2016-03-03
    • 2016-02-26
    • 1970-01-01
    • 2019-12-10
    • 1970-01-01
    • 2018-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多