角度事件处理程序属性更改不会触发侦听器

时间:2016-09-29 10:04:38

标签: javascript angularjs

我使用Angular触发下拉列表,在此应用程序的情况下,在显示下拉菜单之前加载下拉菜单的内容。我想要实现的是能够将下拉指令添加到元素中,但重要的是,我希望下拉列表在元素后出现,而不是中,因为可能会使用各种不同的元素来触发此下拉列表。

我已经完成了所有这些工作,但我觉得它不像我想要的那样 Angular ,因为它似乎需要一本手册$scope.$apply()而且似乎对我来说,如果我正在处理Angular的流程,这应该是不必要的。此外,由于这是用于引发悬停菜单,如果鼠标经过多个触发元素,Angular会因多次应用调用而感到沮丧。

对于HTML,简化版本如下所示:

<div ng-app="example">
    <div example-hover>
    Hover me
    </div>
</div>

使用以下JS:

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

angular.module("example")
             .controller("exampleHoverController", function( $scope ) {
            $scope.showHoverList = false;

            $scope.setHoverList = function(value) {
                console.log("Set hoverlist value: "+value);
                this.showHoverList=value;
                $scope.$apply();
            }
     });

angular.module("example")
             .directive("exampleHover", function( $compile ) {
       return {
           restrict: "A",
           template: '',
           controller: 'exampleHoverController',
           link: function( scope, element) {
                  element.after('<example-dropdown></example-dropdown>');
                $compile(element.parent().find('example-dropdown'))(scope);

                element.bind("mouseover", function() {
                    scope.showHoverList = true;
                  scope.setHoverList(true);
                });
                element.bind("mouseout", function() {
                    scope.showHoverList = false;
                  scope.setHoverList(false);
                });
           }
       }
     });

 angular.module("example")
                .directive("exampleDropdown", function() {
        return {
            restrict: 'E',
          replace: true,
          template: '<div ng-show="showHoverList">I should be visible when hovered!</template>',
          controller: "exampleHoverController"
        };
     });

强制性JSFiddle link。请注意,这是有效的代码,我的问题是:当我更新$scope.$apply中的控制器属性时,如何在不需要调用exampleHoverController的情况下实现相同的目标?

我知道如果我提前知道所有数据,有更简单的方法可以实现这种效果,但是这个代码的真实版本比这个例子做得更多,我需要能够将悬停菜单附加到任何元素,然后在显示时执行一些背景查询,所以如果不是这个确切的模式,我真的需要一些匹配此行为的东西。

1 个答案:

答案 0 :(得分:1)

https://jsfiddle.net/z03huraq/32/

您可以使用exampleHover指令的compile函数:

  • 删除指令属性(因为否则会进入循环)
  • 并将2个鼠标事件直接添加到模板html中

    compile: function(){ return { pre: function(scope, element, attributes, controller, transcludeFn){ element.removeAttr("example-hover") .attr("ng-mouseover","mouseOver()") .attr("ng-mouseout","mouseOut()"); $compile(element)(scope); }, post: function(scope, element, attributes, controller, transcludeFn){ element.after('<example-dropdown></example-dropdown>'); $compile(element.parent().find('example-dropdown'))(scope); } } }

这将允许摘要周期确认事件的存在。