【问题标题】:Angular: event listeners increase incrementally between directive changesAngular:事件侦听器在指令更改之间递增
【发布时间】:2016-07-27 00:13:13
【问题描述】:

我有一个 Angular 状态,它可以在三个模板之间旋转,每个模板都由自己的指令控制。这些指令有事件监听器,但是当我在指令中旋转时,事件监听器加起来一个,在第一次转换到另一个指令之后,一切都开始出现问题。我试图修复这些错误,但无济于事。以下是三个指令之一的示例:

angular.module('app').directive('presetStationOne', function($interval, $parse, $compile, PresetFactory){

    var linker = function(scope, element, attrs){

        PresetFactory.assign(1,6,scope);

        scope.$watch('page1', function(newVal, oldVal){
            if(newVal === true) {
                allEncompassing(document, PresetFactory, scope, "start");
            }
        });
        scope.$on('$destroy', function(){
            allEncompassing(document, PresetFactory, scope, "finish");
        });

    };

    return {
        restrict: 'EA',
        scope: false,
        link: linker,
        templateUrl: 'public/templates/freeplay/presetspage1.html'
    };  
}); 

这里是函数allEncompassing(),它是所有三个presetStation 指令。它们都使用 PresetFactory,当我从一个指令更改为另一个指令时,对 PresetFactory 的调用会逐渐增加。

function allEncompassing(document, PresetFactory, scope, msg){

    if (msg === "finish"){
        removeMyListeners();
    }   

    function clickListen(e){
        var f;
        if (!e.target.attributes.stationnumber){
            if (undefined){
                return;
            } else if(!e.target.parentNode || !e.target.parentNode.parentNode || !e.target){
                return;
            } else if (!e.target.parentNode.parentNode.attributes.hasOwnProperty('stationnumber')){
                return;
            } else {
                return f = e.target.parentNode.parentNode.attributes;
            }
        } else {
            return f = e.target.attributes;
        }
    }

    function resetMouseup(PresetFactory){
        restartMyListeners();
        PresetFactory.mouseUp();            
    }
    function execMouseup(e){
        resetMouseup(PresetFactory);
    }
    function execClickListen(e){
        var f = clickListen(e);
        if (f !== undefined){
            PresetFactory.mouseDown(f, scope);
            scope.$digest();
            restartMyListeners();
        } else {
            return;         
        }
    }

    function restartMyListeners(){
        restartMousedown();
        document.removeEventListener('mouseup', execMouseup);
        document.addEventListener('mouseup', execMouseup);
    }
    function restartMousedown(){
        document.removeEventListener('mousedown', execClickListen);         
        document.addEventListener('mousedown', execClickListen);
    }
    function removeMyListeners(){
        document.removeEventListener('mousedown', execClickListen);         
        document.removeEventListener('mouseup', execMouseup);
    }
    if (msg === "start"){
        restartMyListeners();
    }
}

减少这些事件侦听器的增加并将其保留为单个事件侦听器的最佳方法是什么?

【问题讨论】:

  • 我能想到的最明显的事情就是在模板上添加事件侦听器,让 Angular 处理它们。看起来您正在将点击事件附加到整个页面?像<body data-ng-click="execClickListen"> 这样的东西适合你吗?
  • 我会试一试并报告。
  • 当我遇到您的情况时,我总是会这样做,除非它是正在更改的视图之外的全局元素。您也可以尝试制作仅在初始页面加载时加载并且在切换路线时不会更改的“应用程序”控制器(或我想的指令)。
  • 其实 Shan,我刚刚意识到这可能行不通,因为事件侦听器非常具体:如果鼠标按下不到一秒,“电台拨号”就会改变。如果超过一秒,则保存“无线电预设”。所以我相信某种事件监听器是必要的。
  • @ShanRobertson 其实我可能已经找到了解决方案:stackoverflow.com/questions/25180332/…

标签: javascript angularjs


【解决方案1】:

这就是答案,它比使用事件侦听器要容易得多。我认为我需要事件侦听器,因为我正在观看 mousedown 事件以确定是否应该设置广播电台或更改为广播电台。相反,我使用了$interval 服务和HTML 属性data-ng-mousedown="radioStn(1)" data-ng-mouseup="checkResult()"

var dial = null;
var promise = null;
var time = 0;  
var check = false;

function defaultVal(){
    dial = null;
    promise = null;
    time = 0;
}    

function checkTime(dial, scope, $interval, $rootScope, PresetFactory){
    $interval.cancel(promise);
    if (check === true){
        console.log(dial + ' check is true');
        PresetFactory.setPreset(dial, scope);
    } else {
        console.log(dial + ' check is false');
        PresetFactory.changeStn(dial);
    }
    defaultVal();
}


angular.module('app').directive('presetStationOne', function($rootScope, $interval, $parse, $compile, PresetFactory){

    var linker = function(scope, element, attrs){

        PresetFactory.assign(1,6,scope);

        scope.radioStn = function(x){
            dial = x;
            promise = $interval(function(){
                time += 100;
                console.log(time);
                if (time >= 1000){
                    check = true;
                    checkTime(dial, scope, $interval, $rootScope, PresetFactory);
                    return;
                }
            }, 100);
        };

        scope.checkResult = function(){
            if (check === true){
                check = false;
                return;
            } else {
                checkTime(dial, scope, $interval, $rootScope, PresetFactory);
            }
        };

        scope.$on('$destroy', function(){
            defaultVal();
            check = false;
        });

    };

    return {
        restrict: 'EA',
        scope: false,
        link: linker,
        templateUrl: 'public/templates/freeplay/presetspage1.html'
    };  
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 2018-10-27
    • 1970-01-01
    • 2019-08-06
    相关资源
    最近更新 更多