简体   繁体   English

触发自定义jquery单击Angular自定义指令

[英]Triggering custom jquery click on Angular Custom Directive

I am using a custom directive for multiSelect dropdown. 我在multiSelect下拉菜单中使用了自定义指令。 I needed a custom tirggering of open and close the multiSelect list using a custom button. 我需要使用自定义按钮自定义触发打开和关闭multiSelect列表。

Problem: I got $apply already in progress error 问题:我收到了$ apply正在进行的错误

Solution: To solve this I wrapped my jQuery function in $timeout 解决方案:为了解决这个问题,我将jQuery函数包装在$ timeout中

$timeout(function () {
    $('button.dropdown-toggle').trigger('click');
});

However, now I could make custom click to directive and my multiSelect would open, but now if on 2nd click I want to close the select box, it flickers, and keeps open. 但是,现在我可以对指令进行自定义单击,并且可以打开我的multiSelect,但是现在如果要第二次单击,我想关闭选择框,它会闪烁并保持打开状态。 ;(

Directive: 指示:

if (!parentFound) {
    $scope.$apply(function(){
        $scope.open = false;
    });
}

Can someone propose a solution so that my toggling of multiSelect dropdown works now (after using $timeout) instead of opening only in all clicks? 有人可以提出解决方案,以便我切换multiSelect下拉列表现在起作用(使用$ timeout之后),而不是仅在所有单击中都打开吗?

在此处输入图片说明

Remove it out of $scope.$apply as 将其从$scope.$apply删除$scope.$apply

if (!parentFound) { function(){ $scope.open = false; }; }

For this first needs to understand $scope.$apply() 为此,首先需要了解$ scope。$ apply()

AngularJs creates a "watch" internally for the all data-bindings created in view and call $scope.$digest() which in turns iterate through all watches and checks if any of the watched variables have changed. AngularJs在内部为在视图中创建的所有数据绑定创建一个“监视”,并调用$ scope。$ digest(),它依次遍历所有监视并检查任何监视变量是否已更改。 When you call $scope.$apply() it internally calls $scope.$digest() so data-binding gets refreshed. 当您调用$ scope。$ apply()时,它将在内部调用$ scope。$ digest(),以便刷新数据绑定。

Listener directives, such as ng-click, register a listener with the DOM. 监听器指令(例如ng-click)会向DOM注册一个监听器。 When the DOM listener fires, the directive executes the associated expression and updates the view using the $apply() method. 当DOM侦听器触发时,伪指令执行关联的表达式并使用$ apply()方法更新视图。

When an external event (such as a user action, timer or XHR) is received, the associated expression must be applied to the scope through the $apply() method so that all listeners are updated correctly ( ref ). 收到外部事件(例如用户操作,计时器或XHR)时,必须通过$ apply()方法将关联的表达式应用于作用域,以便正确更新所有侦听器( 参考 )。

So in your case $scope.$apply() is already called on click event and so throwing an error. 因此,在您的情况下,$ scope。$ apply()已在click事件中调用,因此引发错误。

Also would be usefult to read this 这篇也很有用

Only negate the $scope value: 仅取反$scope值:

$scope.$apply(function() {
  if($scope.open) { //only close when it is open
    $scope.open = !$scope.open;
  }
});

If you wish to close the dropdown when you click outside the select box you can use another custom directive, which listens on the window for click events. 如果希望在选择框外单击时关闭下拉列表,则可以使用另一个自定义指令,该指令在窗口上侦听单击事件。 This will broadcast a new event which you can listen for: 这将广播一个新事件,您可以收听:

myApp.directive('dropdownListener', function ($window, $rootScope) {
    return {
        restrict: 'A',

        link: function(scope, element, attr) {
          var w = angular.element($window);

          w.bind('click', function(){
            $rootScope.$broadcast('dropdown:close');
          });
        }
    }
});

This means you can modify the original action by include a listener dropdown:close event: 这意味着您可以通过包含一个listener dropdown:close事件来修改原始操作:

$scope.$on('dropdown:close', function (event, data) {
   $scope.$apply(function() {
      if($scope.open) { //only close when it is open
        $scope.open = !$scope.open;
      }
    });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM