簡體   English   中英

如何在不使用Angular.js中使用$ apply()的情況下編寫此函數

[英]How can I write this function without using $apply() in Angular.js

我有一個小事件處理程序,像這樣響應上/下鍵...

    $scope.$on('handleDownKey', function(){ changeIndex(1) });
    $scope.$on('handleUpKey', function(){ changeIndex(-1) });

    function changeIndex(val){
        $scope.listIndex += val;
        //$scope.$apply();
    }

在我看來,我有一個看起來像這樣的列表

<li ng-class="{selected: listIndex == $index}" ng-repeat="item in items">
    <p>{{item.title}}</p>
    <p>{{item.desc}}</p>
</li>

我的問題是,僅在取消注釋$scope.apply()行時,對listIndex更改才會反映在視圖中。

但是,當我取消注釋該行時, Error: $digest already in progress加載應用程序時收到Error: $digest already in progress消息Error: $digest already in progress

我的猜測是我不是以Angular的方式進行操作,但是如何用Angular編寫這樣的示例?

對於那些想知道handleKeyDown來自何處的人,我有一條指令可以接收鍵盤事件並將它們傳遞給名為KeyboardSrv的服務。 指令看起來像這樣...

myModule.directive('onKeydown', function(KeyboardSrv) {
    return function(scope, elm, attrs) {
        function applyKeydown() {
          scope.$apply(attrs.onKeydown);
        };           

        elm.bind('keydown', function(evt) {
            KeyboardSrv.prepareEvent(evt)
        });
    };
});

服務看起來像這樣...

function KeyboardSrv($rootScope){

    var KeyboardSrv = {};       
    KeyboardSrv.code;
    KeyboardSrv.evt;

    KeyboardSrv.prepareEvent = function(evt){
        KeyboardSrv.code = evt.which;
        KeyboardSrv.evt = evt;

        if(KeyboardSrv.code == 40){
            KeyboardSrv.broadcastEvent("handleDownKey", evt);
        }

        if(KeyboardSrv.code == 38){
            KeyboardSrv.broadcastEvent("handleUpKey", evt);
        }

    }

    KeyboardSrv.broadcastEvent = function(msg, event){
        $rootScope.$broadcast(msg, event);
    }

    return KeyboardSrv;

};

因此,有一種方法可以在Angular中處理此問題而不會觸發錯誤。 基本上,angular在運行$digest時都會接受此更改。 我這里的問題是我的changeIndex方法沒有觸發$digest ,所以我必須手動調用$apply

但是,在應用程序啟動時,將changeIndex方法,而$digest仍在運行,這會引發錯誤,因為您無法在$digest另一個調用中調用$digest

Angular確實提供了一種方法來告知$digest當前是否正在運行,因此應像這樣處理對$apply的調用...

$scope.listIndex += val
if(!$$phase) $scope.$apply();

如果$$phase為真,則angular當前運行$digest ,我們的更改將自動進行。 如果$$phase為假,則需要手動觸發$apply

雖然這是一個修復程序,但我仍然希望不必手動調用$ apply。 感覺有點像手動引用計數,並擁有以這種方式工作的方法,這對我來說很有趣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM