0

当用户按下 esc 键时,我试图清除过滤器的输入字段。一旦我输入指令的标记,过滤器就会完全停止工作。

我的标记如下:

<div ng-app='App'>
  <div ng-controller="MyCtrl">
    <input type="text" ng-model="itemSearch" clear-input clear="clearFilter()" />
    <button ng-click="clearFilter()">Clear</button>
    <ul>
      <li ng-repeat="item in items|filter:itemSearch"> <span>{{item.value}}</span>
      </li>
    </ul>
  </div>
</div>

JavaScript如下:

var app = angular.module('App', []);

function MyCtrl($scope) {
  $scope.items = [
    {value: 'one two three'}, 
    {value: 'four five six'}
  ];
  $scope.clearFilter = function () {
    $scope.itemSearch = '';
  };
}

app.directive('clearInput', function () {
  function isEscapeKey(keyCode) {
    if (keyCode === 27) {
      return true;
    }
      return false;
    }
    return {
        restrict: 'A',
       scope: {
        clear: '&'
    },
    link: function (scope, element) {
      element.keyup(function (event) {
        if (isEscapeKey(event.keyCode)) {
          scope.clear();
        }
      });
    }
  };
});

我在这里有示例代码:http: //jsfiddle.net/darrenthomas/cbcpq/1/

我想指出,我不是一位经验丰富的 JavaScript 程序员,而且我是 AngularJS 的新手。我还查看了如何将多个属性传递给 Angular.js 属性指令?但我无法获得有效的解决方案。

4

5 回答 5

1

消除 :

scope: {
        clear: '&'
    },

在指令中。我们在这里不需要隔离范围。

就像 Webnet 说的那样使用:

element.bind('keyup', function (event) {
    if (isEscapeKey(event.keyCode)) {
      scope.clear();
    }
  });

之后,添加$apply到您的指令:

app.directive('clearInput', function () {
    function isEscapeKey(keyCode) {
        if (keyCode === 27) {
            return true;
        }
        return false;
    }
    return {
        restrict: 'A',
        link: function (scope, element) {
            element.bind('keyup', function (event) {
                if (isEscapeKey(event.keyCode)) {                                  
                     scope.$apply(function(){scope.clearFilter();});
                }
            });
        },
    };
});

工作演示Fiddle

于 2013-10-30T15:09:25.627 回答
1

如果只想清除字段,则不需要在编写的自定义指令中隔离范围。您可以简单地使用$eval()函数scope来间接执行clearFilter()函数

app.directive('clearInput', function () {
function isEscapeKey(keyCode) {
    if (keyCode === 27) {
        return true;
    }
    return false;
}
return {
    link: function (scope, element, attrs) {
        element.bind('keyup',function (event) {
            if (isEscapeKey(event.keyCode)) {
                scope.$eval(attrs.clear);
                scope.$apply();
            }
        });
    },
  };
});

这是一个更新的小提琴

于 2013-10-30T15:39:47.303 回答
0

在您的示例中,浏览器的控制台(可通过 Chrome 中的 Ctrl + Shift + I 访问)显示错误TypeError: Object [object Object] has no method 'keyup'

你的代码应该是...

  element.bind('keyup', function (event) {
    if (isEscapeKey(event.keyCode)) {
      scope.clear();
    }
  });

但它看起来也没有在您的控制器中定义 clear() 。

于 2013-10-30T15:00:19.520 回答
0

更新了小提琴。http://jsfiddle.net/cbcpq/10/。希望这可以帮助

app.directive('clearInput', function () {
function isEscapeKey(keyCode) {
    if (keyCode === 27) {
        return true;
    }
    return false;
}
return {
    restrict: 'A',
    scope: {
        clear: '&'
    },
    link: function (scope, element) {
        $(element).keyup(function (event) {
            if (isEscapeKey(event.keyCode)) {
                scope.itemSearch = "";
                scope.$apply();
            }
        });
    },
};

});

于 2013-10-30T15:16:44.497 回答
0

您可能有多个答案可供选择。但是如果你想让这个clear-input指令完全可重用,那么我相信你将不得不使用$parse. 主要是因为你不能在那里使用isolate scopewith ng-model。至少不是完全了解正在发生的事情。

这是指令的代码:

app.directive('clearInput', function ($parse) {
    function isEscapeKey(keyCode) {
        return keyCode === 27;
    }
    return {
        require : "^ngModel",
        link: function (scope, element,attrs,ctrl) {
            if(!ctrl){
                return;
            }
            var ngModelSetter = $parse(attrs.ngModel).assign;
            element.bind("keyup",function (event) {
                if (isEscapeKey(event.which)) {
                    ngModelSetter(scope,"");
                    scope.$apply();
                }
            });
        }
    };
});

一个 plunker 展示了它的用途:

http://plnkr.co/edit/z0Td2tR3JiVPFsbgauhj?p=preview

于 2013-10-30T15:46:16.637 回答