2013-08-22 44 views
8

这里是jade的观点:如何在Angular的文件输入中触发'click'事件?

button#save-csv-btn(ng-click="click()") Export CSV 
input#save-csv(style="display:none", type="file", onchange="angular.element(this).scope().saveCSVFileChanged(this)") 

JS:

$scope.click = -> 
    # $('#save-csv').trigger('click') 

错误,我得到:

Error: $apply already in progress 
+0

您可能希望在这里包含实际的javascript和来自jade的输出,而不是预处理的代码,因为更多的人可以提供帮助。一般来说,这意味着你在$ scope中触发的函数中调用了$ scope($ apply())。apply() – shaunhusain

+0

此外,这似乎通常是一个糟糕的主意,尽管即使假定某个元素是操作DOM有没有使用指令的名称作为封装逻辑的手段并不好。 – shaunhusain

+0

通过隐藏实际的并触发其他方法的点击,这是一种非常标准的文件输入方式。 问题是角度抛出一个错误,因为它适用于一个应用 – mcfedr

回答

11

我改变$scope.click功能触发在setTimeout输入点击。这让第一个$apply完成,然后会触发另一个。

$scope.click = function() { 
    setTimeout(function() { 
     inputEl.click(); 
    }, 0); 
} 

请注意,我用setTimeout,不$timeout$timeout也将在$apply区块内。

+0

我有同样的问题作为OP,并使用$超时而不是setTimeout为我工作以及 – inolasco

1

我刚碰到这个问题,写了一个解决方案。你可以编写一个自定义指令,它由一个容器,一个按钮和一个带有文件类型的输入元素组成。使用CSS,然后将输入放置在自定义按钮上,但不透明度为0.您将容器的高度和宽度设置为按钮的偏移宽度和高度,并将输入的高度和宽度设置为容器的100%。

指令

angular.module('myCoolApp') 
    .directive('fileButton', function() { 
    return { 
     templateUrl: 'components/directives/fileButton/fileButton.html', 
     restrict: 'E', 
     link: function (scope, element, attributes) { 

     var container = angular.element('.file-upload-container'); 
     var button = angular.element('.file-upload-button'); 

     container.css({ 
      position: 'relative', 
      overflow: 'hidden', 
      width: button.offsetWidth, 
      height: button.offsetHeight 
     }) 

     } 

    }; 
    }); 

玉模板,如果你使用的是如果你使用的HTML

<div class="file-upload-container"> 
    <button class="file-upload-button"></button> 
    <input class="file-upload-input" id="file-upload" type="file" onchange="doSomethingWhenFileIsSelected()" /> 
</div> 

的CSS

div(class="file-upload-container") 
    button(class="file-upload-button") + 
    input#file-upload(class="file-upload-input", type='file', onchange="doSomethingWhenFileIsSelected()") 

在HTML同一模板

.file-upload-button { 
    margin-top: 40px; 
    padding: 30px; 
    border: 1px solid black; 
    height: 100px; 
    width: 100px; 
    background: transparent; 
    font-size: 66px; 
    padding-top: 0px; 
    border-radius: 5px; 
    border: 2px solid rgb(255, 228, 0); 
    color: rgb(255, 228, 0); 
} 

.file-upload-input { 
    position: absolute; 
    top: 0; 
    left: 0; 
    z-index: 2; 
    width: 100%; 
    height: 100%; 
    opacity: 0; 
    cursor: pointer; 
}