2014-02-12 16 views
0

我有一個功能,讓我們說:

$scope.addNode = function (param) { 
    //this is a function to add a child to a tree view node, sent via the param argument 
    var newNode = { 
     //add the different properties I need for the new node 
    }; 
    if(param.hasOwnProperty('children') && param.children != null) { 
     param.children.push(newNode); 
    } 
    else { 
     param.children = []; 
     param.children.push(newNode); 
    } 

    $scope.$apply(); // calling $apply because I need the newNode to be rendered 

    $scope.setFocusedNode(newNode); //highlight the new node, change attributes, etc 
    $scope.editNodeText(newNode); //call inline Editing for the new node, which also involves DOM manipulation; this is basically where everything fails because without the apply, the DOM element for the newNode doesn't exist. 

} 

我使用同樣的功能從一個jQuery keyup事件,並從NG點擊指令。 該代碼從keyup事件工作正常,但從指令調用時,我得到一個「$應用已在進行中」的錯誤,因爲ng-click已經做了天生的$應用。

但是,刪除$ apply也不起作用,因爲我需要爲它後面的代碼更新範圍AND我不能用普通的onclick替換ng-click,因爲click函數也是該範圍內的對象可以更改。

有沒有辦法在沒有得到「$ apply already in progress」錯誤的情況下說「刷新範圍」?請注意,即使我得到的錯誤,範圍得到更新corectly和工作好,即使從ng點擊調用(除了IE只是扼流圈和javascript停止工作)

+0

你可以考慮這個https://coderwall.com/p/ngisma –

+0

@Joel_Blum我已經試過,但這不是我要找的。即使當我從ng-click(因此,在一個隱式應用中)調用函數時,我仍然需要執行$ apply,因爲我需要爲函數的下一部分更新範圍。 – Bogdan

+1

你能再提供一些代碼嗎?在申請之前和之後你做了什麼?我認爲你需要找到一個更清潔的解決方案... –

回答

0

我找到了解決問題的辦法。代碼現在看起來像這樣:

$scope.addNode = function (param) { 
    //this is a function to add a child to a tree view node, sent via the param argument 
    var newNode = { 
     //add the different properties I need for the new node 
    }; 
    if(param.hasOwnProperty('children') && param.children != null) { 
     param.children.push(newNode); 
    } 
    else { 
     param.children = []; 
     param.children.push(newNode); 
    } 


    $timeout(function() { 
     $scope.setFocusedNode(newNode); //highlight the new node, change attributes, etc 
     $scope.editNodeText(newNode); //call inline Editing for the new node, which also involves DOM manipulation; this is basically where everything fails because without the apply, the DOM element for the newNode doesn't exist. 
    }, 0); 

} 

而我簡單地調用$ scope。$ apply(addNode)從jquery keyup函數中調用它時。

$ timeout所做的是延遲這兩個函數,直到瀏覽器完成對$ scope的更改呈現。我不完全瞭解它是如何做到的,但它現在可行。

0

正確的方法是刪除$scope.$apply從功能和 從jQuery的使用

$scope.apply($scope.addNode(arguments)); 

時調用,並從使用角度範圍內調用函數時

$scope.addNode(arguments); 
+0

我試過了,但是我不能這樣做,因爲第二個註釋部分。該函數基本上是「添加節點,渲染節點(這是我需要應用的位置),對渲染的節點進行一些操作。如果我將所有內容都封裝在一個應用中,當我到達階段3時,節點仍然不會呈現。 – Bogdan

+0

那麼使用相同的函數是錯誤的做法...您可能使用兩種不同的函數,或者您可以用髒方法來執行它 - 檢查$在$ apply - > if(!$ scope。$$階段){$ scope。$ apply();} – doodeec

+0

之前函數內部的$ $$階段,但它沒有任何意義,您需要調用apply,即使摘要循環已在進行中 – doodeec

0

你可以試試這個?

$scope.addNode = function (node) { 
    $scope.$apply(function() { 
      //do something to $scope object 
     }); 

    //do something that needs the scope to be refreshed 
} 
+1

它是一樣的...如果你從角度內部調用它,摘要將已經在進行中 – doodeec

+0

你是說這不起作用嗎?我沒有自己嘗試過。 – user1477388

+0

它不會......問題在於,在兩種情況下重用函數 - 從jquery調用,從角度調用。對於每種情況,都必須以不同的方式調用以避免摘要錯誤 – doodeec

相關問題