角度指令明确字段

时间:2015-03-26 19:49:02

标签: javascript angularjs angularjs-directive angular-directive

我正在尝试在我的离子应用程序中实现一个角度指令,以向文本字段添加“X”按钮,单击该按钮可清除文本。代码基于此repo:https://github.com/amageed/angular-resetfield

我无法获得名为...的重置匿名函数。重置日志语句未显示,但链接语句执行:

.directive('resetField', ['$compile', '$timeout', function($compile, $timeout) {
    return {
        require: 'ngModel',
        scope: {},
        link: function(scope, el, attrs, ctrl) {

            console.log('linking ');

            // limit to input element of specific types
            var inputTypes = /text|search|tel|url|email|password/i;
            if (el[0].nodeName === "INPUT") {
                if (!inputTypes.test(attrs.type)) {
                    throw new Error("Invalid input type for resetField: " + attrs.type);
                }
            } else if (el[0].nodeName !== "TEXTAREA") {
                throw new Error("resetField is limited to input and textarea elements");
            }

            // compiled reset icon template
            var template = $compile('<i ng-show="enabled" ng-click="reset();" class="icon ion-close reset-field-icon"></i>')(scope);
            el.addClass("reset-field");
            el.after(template);

            scope.reset = function() {
                console.log('resetting');
                ctrl.$setViewValue(null);
                ctrl.$render();
                $timeout(function() {
                    el[0].focus();
                }, 0, false);
                scope.enabled = false;
            };

            el.bind('input', function() {
                scope.enabled = !ctrl.$isEmpty(el.val());
            })
            .bind('focus', function() {
                $timeout(function() {
                    scope.enabled = !ctrl.$isEmpty(el.val());
                    scope.$apply();
                }, 0, false);
            })
            .bind('blur', function() {
                $timeout(function() {
                    scope.enabled = false;
                    scope.$apply();
                }, 0, false);
            });
        }
    };
}]);

以下是HTML中的用法:

<input type="text" placeholder="Search" ng-model="query" autocorrect="off" reset-field>

2 个答案:

答案 0 :(得分:2)

  

问题出现是因为blur事件(总是)在click事件之前触发。

blur事件触发时,$scope.enabled变为false,因此在click事件触发之前按钮会立即消失。

  

你需要的是一个(总是)在blur之前触发的事件,即ng-mousedown


您需要做的就是改变:

ng-click="reset();">

ng-mousedown="reset();">

它有效。


由于事件现在总是以正确的顺序触发,因此您的代码中没有任何其他内容可以更改。

X图标可以位于页面的任何位置,它仍可以使用。

如果您希望将其放在输入框上,只需添加:

style="position:relative;right:15px;top:1px;cursor: pointer;cursor: hand;"

<i>代码。


请找到angular directive clear field代码的working plunker


要了解clickmousedown事件之间的差异,please read this page

要测试DOM事件的顺序,请check this pen

----------

更新:如何处理Cordova环境的案例

我(姗姗来迟)意识到Cordova环境没有像浏览器那样处理事件。

This post提供了mousedownmouseupmousemove事件的等效表。

由于touchstart相当于mousedownng-mousedown="reset();">应在此解决方案中替换ng-touchstart="reset();">;

ng-touchstart不存在开箱即用,但根据此github repo,您可以像这样创建指令:

.directive("ngTouchstart", function () {
  return {
    controller: function ($scope, $element, $attrs) {
      $element.bind('touchstart', onTouchStart);

      function onTouchStart(event) {
        var method = '$scope.' + $element.attr('ng-touchstart');
        $scope.$apply(function () {
          eval(method);
        });
      };
    }
  };
});

到目前为止,我还没有在Cordova环境中测试这个解决方案,但我会...

----------

其他信息:在我发布上述答案后,您发表了以下评论:

这不起作用。它可能与我在查询中使用ng-model的事实有关吗?另外,我尝试将重置代码放入bind中,clear确实有效,但是过滤器未重新应用。

“是的,它适用于plunker但不适用于ios sim。”


回答你的评论

我的回答完全基于您提供的指令代码和HTML代码。

您的问题是:“我无法获得名为的重置匿名函数...即重置日志语句未显示

我尽可能精确地回答你的问题,解释问题并提供一个有效的说明来证明这一点:无法调用重置函数,因为焦点事件优先;当您将ng-click替换为ng-mousedown时,它可以正常工作,详细信息请参阅提供的来源,并在我提供的插件中显示。

然后回答了原始帖子中的问题,解释了问题,并提供了有效的解决方案。


你提到ios。我刚刚在iPad上测试了我的plunker:它完美无缺。如果我提供的解决方案与之不兼容的特定设备,我将很乐意尝试找到解决方法。

现在您似乎还有其他无关的问题,原始帖子中提供的代码无法预见这些问题。

如果是这样,请提出另一个问题;你可以在我的plunker中复制/粘贴代码,提供一个新的plunker和尽可能多的关于你当前问题的细节。

同样,我会很乐意尽力回答我的能力......

答案 1 :(得分:0)

我的代码正常运行, check this JS Bin

我改变了:

class="icon ion-close reset-field-icon"

to font awesomes:

class="fa fa-times-circle"

它有效。

您还在问题中遗漏了一些其他代码。看看你错过了什么。