【问题标题】:$scope.$apply() in angular working but throwing error$scope.$apply() 在角度工作但抛出错误
【发布时间】:2015-05-29 15:32:53
【问题描述】:

我将孤立的示例放在一个 jsbin 中: http://jsbin.com/deqerelita/1/

场景 基本上这个想法很简单。单击一个按钮,控制器添加到模型中,视图会相应地更新为隐藏的输入类型 =“文件”。视图更新后,控制器点击最后添加的文件输入。

问题 当控制器在运行 $scope.$apply() 之前单击文件输入时,直到第二次单击之前什么都没有发生,大概是因为 Angular 尚未注册新输入。 当我运行 $scope.$apply() 时,控制台会抛出错误,但会单击输入。

这是 html:

  <div ng-controller="fileButtons">
    <input type="button" ng-click="handleImage.add()" value="add another file button"/>

    <div class="imageUploadPreviewContainer">
        <div class="imageUploadPreview hide" data-ng-repeat="file in files" file-index="{{$index}}">
            <input type="file" class="hide"/>
        </div>
    </div>
  </div>

</div></div>

这里是 Angular js:

 var myApp = angular.module('myApp', []);
myApp.controller('fileButtons', ['$scope', '$log',
    function($scope, $log){
        $scope.files = [];
        $scope.handleImage = {
            add: function(){
              $scope.files.push({
                state : 'started'
              });
              $log.log('added');
              $scope.$apply(); 
              angular.element('.imageUploadPreviewContainer .imageUploadPreview:last input[type=file]').trigger('click')
            }
        }
    }
]);

对 Angular 来说是全新的,所以请原谅任何令人讨厌的设计缺陷

【问题讨论】:

  • 所以当你第一次点击按钮时,应该会出现一个打开的文件对话框?..如果不使用 $apply 就不会出现?我理解的对吗?

标签: javascript angularjs


【解决方案1】:

我会使用$timeout

var myApp = angular.module('myApp', []);
myApp.controller('fileButtons', ['$scope', '$log','$timeout', function($scope, $log, $timeout)
{
    $scope.files = [];
    $scope.handleImage = {
      add: function()
      {
        $scope.files.push({state : 'started'});
        $log.log('added');
        $timeout(function()
        {
          angular.element('.imageUploadPreviewContainer .imageUploadPreview:last input[type=file]').trigger('click')
        },0);
      }
    };
  }
]);

【讨论】:

  • 100ms超时不需要。
  • 啊……我不知道角度自定义 setTimeout 函数。我正在尝试使用香草超时,但它什么也没做。谢谢,这已经奏效了。
  • 是的,当我开始使用 Angular 时,我遇到了同样的问题。仍然使用 vanilla js,我经常发现自己尝试使用 $timeout
  • :) 非常喜欢。我想我一定尝试过一百万种变体来让这件事发挥作用哈哈
【解决方案2】:

由于$scope.$apply() 触发$digest,并且在任何时间点都只能有一个$digest$apply 操作正在进行中。

你应该使用$timeout

 $timeout(function(){
   angular.element('.imageUploadPreviewContainer .imageUploadPreview:last input[type=file]').trigger('click')
 }, 0) 

注意:您应该在控制器中注入 $timeout。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-08
    • 2016-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-29
    • 2015-05-16
    • 1970-01-01
    相关资源
    最近更新 更多