如果我已处于$ apply阶段,我可以刷新范围吗?

时间:2014-02-12 15:23:02

标签: javascript angularjs

我有一个函数让我们说:

$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-click指令中使用相同的函数。 代码在keyup事件中正常工作,但是当从指令调用它时,我得到一个“$ apply has in progress”错误,因为ng-click已经实现了$ apply。

但是,删除$ apply也不起作用,因为我需要为其后面的代码更新范围而且我无法用普通的onclick替换ng-click,因为click函数也是一个属性。范围内的对象可以改变。

有没有办法说“刷新范围在这里”而没有得到“$ apply has in progress”错误?请注意,即使我得到了错误,范围也会被核心更新并且即使从ng-click调用也能正常工作(除了在IE中只是窒息并且javascript完全停止工作)

3 个答案:

答案 0 :(得分:0)

正确的方法是从函数中删除$scope.$apply 从jquery使用时调用

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

从角度使用中调用函数

$scope.addNode(arguments);

答案 1 :(得分:0)

你能试试吗?

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

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

答案 2 :(得分: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);

}

我从jquery keyup函数调用它时只调用$ scope。$ apply(addNode)。

$ timeout的作用是延迟这两个函数,直到浏览器完成对$ scope的更改。我不完全理解它是如何做到的,但它现在有效。