如何将方法传递给角度属性指令?

时间:2013-10-30 14:51:14

标签: angularjs angularjs-directive

当用户按下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的新手。我也看过How do I pass multiple attributes into an Angular.js attribute directive?,但无法找到解决方案。

5 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

如果您只想清除该字段,则无需在您编写的自定义指令中隔离范围。您只需使用$eval()的{​​{1}}函数间接执行scope函数

clearFilter()

这是更新的Fiddle

答案 2 :(得分: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()。

答案 3 :(得分: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();
            }
        });
    },
};

});

答案 4 :(得分:0)

您可能有多个答案可供选择。但是如果你想让这个clear-input指令完全可重复使用那么我相信你必须使用$parse。主要是因为您无法在isolate scope使用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();
                }
            });
        }
    };
});

一名说明其用途的掠夺者:

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