Angular指令清空字段

4
我正在尝试在我的ionic应用程序中实现一个angular指令,以添加一个“X”按钮到文本字段中,当点击该按钮时会清除文本。该代码基于此存储库: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>

为什么不创建一个IIFE,而不是需要调用的$scope函数? - felipekm
2个回答

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>标签


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


要了解clickmousedown事件之间的区别,请阅读此页面

要测试DOM事件的顺序,请检查此笔

----------

更新: 如何处理Cordova环境的情况

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

这篇帖子给出了mousedownmouseupmousemove事件的等效表。

由于touchstart相当于mousedown,所以在此解决方案中应该将ng-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中,清除确实有效,但过滤器不会重新应用。"

"是的,它在plunker中有效,但在ios sim中无效。"
回答您的评论
我的回答仅基于您提供的指令代码和HTML代码。
您的问题是:" 我无法调用重置匿名函数...即重置日志语句不显示"
我非常小心地回答了您的问题,尽可能精确地解释了问题,并提供了一个有效的plunker来证明这一点: 重置功能无法调用,因为焦点事件优先级较高; 当您将 ng-click 替换为 ng-mousedown 时,它可以正常工作,如所提供的来源详细说明并在我提供的plunker中显示。
然后回答了您原始帖子中的问题,解释了问题,并提供了一个可行的解决方案。
您提到了iOS。我刚在iPad中测试了我的plunker:它完美地工作。如果有特定设备与我提供的解决方案不兼容,则我将乐意尝试找到解决方法。
现在似乎您有其他不相关的问题,这些问题无法通过原始帖子中提供的代码预见。
如果是这种情况,请提出另一个问题;您可以复制/粘贴我的plunker中的代码,提供一个新的plunker以及有关您当前问题的尽可能多的细节。
再次感谢,我将竭尽所能回答...

这个没有起作用。可能是因为我在查询中使用了ng-model有关系吗?另外,我尝试将重置代码放入绑定中,清除确实起作用,但过滤器没有重新应用。 - thebiglebowski11
你尝试过 Plunker 吗? - Manube
我知道我已经选择了你的答案...但是在设备上测试时仍然无法正常工作。在浏览器中,它按预期工作,但在应用程序中却不行。 - thebiglebowski11
iOS 设备、模拟器和物理设备 - thebiglebowski11
你是在浏览器中运行它吗? - thebiglebowski11
显示剩余7条评论

0

我已经让你的代码运行起来了,请查看这个 JS Bin

我进行了如下更改:

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

关于字体神器:

class="fa fa-times-circle"

它起作用了。

你在问题中还遗漏了一些其他代码。看一下并找出你错过的部分。


什么不起作用?当您输入时,会得到X。当您单击X时,它会清除输入并在控制台中打印重置。至少在我的电脑上可以工作。 - nilsi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接