以编程方式调用输入类型文件的click方法时获取$ rootScope:inprog错误

时间:2014-12-05 12:22:22

标签: javascript jquery html angularjs

我想创建自定义文件上传组件。我在html中执行了以下代码

HTML CODE

<input id="upload" type="file" style="display: none;">// don`t want to render default
<button class="parimarybtnVD" type="button" ng-click="clickUpload()">Browse</button>

JS CODE

$scope.clickUpload = function() {
    angular.element('#upload').trigger('click');
};

但点击“按钮”后会出现以下错误。

           Error: [$rootScope:inprog] http://errors.angularjs.org/1.2.16/$rootScope/inprog?p0=%24apply
at Error (<anonymous>)
at http://localhost:7001/RightsWeb/scripts/resource/angular.min.js:6:450
at l (http://localhost:7001/RightsWeb/scripts/resource/angular.min.js:102:171)
at h.$digest (http://localhost:7001/RightsWeb/scripts/resource/angular.min.js:105:497)
at HTMLDocument.D (http://localhost:7001/RightsWeb/scripts/utill/ui-bootstrap-tpls-0.11.0.min.js:9:14775)
at HTMLDocument.f.event.dispatch (http://localhost:7001/RightsWeb/extResources/jquery/jquery-1.7.1.min.js:3:4351)
at HTMLDocument.h.handle.i (http://localhost:7001/RightsWeb/extResources/jquery/jquery-1.7.1.min.js:3:328)
at Object.f.event.trigger (http://localhost:7001/RightsWeb/extResources/jquery/jquery-1.7.1.min.js:3:3038)
at <error: TypeError: Accessing selectionDirection on an input element that cannot have a selection.>
at Function.e.extend.each (http://localhost:7001/RightsWeb/extResources/jquery/jquery-1.7.1.min.js:2:11937) 

有人能告诉我为什么会收到此错误吗?如果有更好的方法在angularjs中进行自定义文件上传,请告诉。谢谢你。

2 个答案:

答案 0 :(得分:11)

在任何时间点的角度中,只能进行一次$digest$apply操作。

使用$timeout

$scope.clickUpload = function() {
    $timeout(function() {
        angular.element('#upload').trigger('click');
    }, 1);
};

或者,我建议你使用

<button 
    class="parimarybtnVD" 
    type="button" 
    onclick="document.getElementById('upload').click()">Browse</button>

答案 1 :(得分:1)

我知道这已经过时了,但是我遇到了同样的问题,我想提供另一个解决方案,尽管$timeout解决方案也适用于我。一般来说,除非绝对必要,否则我不想使用它;在这种情况下,它确实不是。

这里发生了这个应用错误,因为当你在angular.element('#upload').trigger('click');方法中调用clickUpload方法时,angularjs还没有完成摘要周期,直到函数返回,但是我们继续执行另一个单击以编程方式触发另一个摘要,所以基本上,我们唯一需要做的就是等待摘要完成(这是$ timeout所做的事情,除非它执行此操作,因为它允许方法在启动点击之前返回),这可以使用$scope.$$postDigest

完成

这意味着将代码更改为以下内容:

$scope.clickUpload = function() {
    $scope.$$postDigest(function() {
        angular.element('#upload').trigger('click');
    });
};

在我看来,这是更简洁的方法,因为$scope.$$postDigest被指定等待当前的摘要周期,而$timeout解决了问题,因为它在clickUpload返回后运行点击