2017-07-19 116 views
1

我有一個Angular應用程序,並且我在使用Javascript和超時的按鈕上使用活動狀態(顏色更改)。像這樣的事情在我的服務:角度狀態轉換暫停超時

HTML:

<div class="btn-numeric" ng-mousedown="highlightButtonThenAddValue(4, $event)">4</div> 

控制器代碼:

var abc = []; 

var highlightButtonTouch = function (event, addClassName) { 
    var element = event.currentTarget; 
    var currClasses = element.classList.add(addClassName); 
    setTimeout(function() { 
    element.classList.remove(addClassName); 
    }, 100); 


$scope.highlightButtonThenAddValue = function (value, event) { 
    log.debug("button pressed on screen, button value: " + value); 
    highlightButtonTouch(event, 'btn-numeric-active'); 
    $scope.add_value(value); 
}; 

$scope.add_value(value) { 
    abc.push(value); 
    if (abc.length === 6) { 
     $state.go(newState); 
    } 
} 

這工作正常,如果按鈕顏色的變化是相同的狀態。但是,當添加足夠的值時,我需要使用state.go來更改狀態,並且在這種情況下,即使在100ms之後,類'btn-numeric-active'也不會被刪除,而是將css更改爲添加btn-numeric-active停留直到狀態改變。我在新狀態上定義了一些解決方法 - 我正在將API調用到服務器。

只有將Chrome性能選項卡中的CPU降至10Xslowdown時,才能看到此問題。但我的應用程序應該運行在慢速機器上。

有沒有人遇到過類似的問題?對於如何解決這個問題,有任何的建議嗎 ?

事情我已經嘗試:

我不能使用:active僞類,因爲這使得即使在觸摸和拖拽活躍狀態,而點擊未註冊。

我已經嘗試將元素定義爲rootScope變量,但那也不能解決問題。

任何建議是值得歡迎的。

+0

你可以嘗試使用'$ timeout'而不是'setTimeout'嗎? – Icycool

+0

@lcycool試過。行爲沒有變化。 – Neha

回答

0

現在我知道是什麼問題,是因爲它的JavaScript的工作方式。

超時回調被添加到調用堆棧中。在進行狀態更改時,我有一些「解決方法」,我在其中進行API調用,那些也在調用堆棧中添加回調,並且它是一個堆棧,在回調超時之前正在處理解析的回調。

因此,element.classList.remove(addClassName);行正在所有完成狀態轉換的API調用後執行。我不得不作出以下修改我的代碼,事情的工作:

var highlightButtonTouch = function (event, addClassName) { 
    var deferred = $q.defer(); 
    var element = event.currentTarget; 
    var currClasses = element.classList.add(addClassName); 
    setTimeout(function() { 
    element.classList.remove(addClassName); 
    deferred.resolve(); 
    }, 100); 
    return deferred.promise; 
} 

並在控制器:

$scope.highlightButtonThenAddValue = function (value, event) { 
    log.debug("button pressed on screen, button value: " + value); 
    highlightButtonTouch(event, 'btn-numeric-active').then(function() { 
     $scope.add_value(value); 
    }); 
}; 

這解決了這個問題。

愚蠢的我,我應該不斷提醒自己基本的javascript行爲 - 事件循環和調用堆棧。

1

你可以嘗試將它包裝在指令中嗎?

angular.module('test', []) 
 
.controller('TestController', TestController) 
 
.directive('fancyButton', fancyButtonDirective); 
 

 
function TestController() {} 
 

 
function fancyButtonDirective() { 
 
    return { 
 
    scope: { name: '@' }, 
 
    template: '<button type="button" ng-mouseover="highLight()">{{name}}</button>', 
 
    link: function(scope, element, attrs) { 
 
     scope.highLight = function() { 
 
     var button = element.find('button')[0]; 
 
     button.classList.add('light'); 
 
     setTimeout(function() { button.classList.remove('light'); }, 200); 
 
     } 
 
    } 
 
    } 
 
}
.light { 
 
    background-color: yellow; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script> 
 
<div ng-app='test' ng-controller='TestController'> 
 
    <fancy-button name="Fancy 1"></fancy-button> 
 
</div>

+0

感謝您的建議。但是我發現問題是不同的 - 它與JavaScript回調之後執行javascript調用堆棧和超時回調有關。請在下面找到我的答案。 – Neha