here is the view in jade
:
这里是玉的观点:
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:
JS:
$scope.click = ->
# $('#save-csv').trigger('click')
Error I get:
我得到的错误:
Error: $apply already in progress
3 个解决方案
#1
11
I changed $scope.click
function to trigger the input click in a setTimeout
. This lets the first $apply
finish, and then will trigger another one.
我更改了$ scope.click函数以触发setTimeout中的输入单击。这允许第一个$ apply完成,然后将触发另一个。
$scope.click = function() {
setTimeout(function() {
inputEl.click();
}, 0);
}
Note that I use setTimeout
, not $timeout
. $timeout
would also be inside an $apply
block.
请注意,我使用setTimeout,而不是$ timeout。 $ timeout也在$ apply块内。
#2
3
The idea was to use button to 'emulate' the file input; I achieved this using http://gregpike.net/demos/bootstrap-file-input/demo.html.
想法是使用按钮来“模拟”文件输入;我使用http://gregpike.net/demos/bootstrap-file-input/demo.html实现了这一点。
input#save-csv(type="file", title="Export to CSV", onchange="angular.element(this).scope().saveCSVFileChanged(this)")
#3
1
I just came across this problem and have written a drop in solution. You can write a custom directive composed of a container, a button, and an input element with type file. With CSS you then place the input over the custom button but with opacity 0. You set the containers height and width to exactly the offset width and height of the button and the input's height and width to 100% of the container.
我刚刚遇到了这个问题并写了一个解决方案。您可以编写由容器,按钮和类型为file的input元素组成的自定义指令。使用CSS,然后将输入放在自定义按钮上,但不透明度为0.您可以将容器的高度和宽度设置为按钮的偏移宽度和高度,输入的高度和宽度设置为容器的100%。
the directive
指令
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
})
}
};
});
a jade template if you are using jade
如果你正在使用玉石的玉石模板
div(class="file-upload-container")
button(class="file-upload-button") +
input#file-upload(class="file-upload-input", type='file', onchange="doSomethingWhenFileIsSelected()")
the same template in html if you are using html
如果你使用html,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>
the css
css
.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;
}
#1
11
I changed $scope.click
function to trigger the input click in a setTimeout
. This lets the first $apply
finish, and then will trigger another one.
我更改了$ scope.click函数以触发setTimeout中的输入单击。这允许第一个$ apply完成,然后将触发另一个。
$scope.click = function() {
setTimeout(function() {
inputEl.click();
}, 0);
}
Note that I use setTimeout
, not $timeout
. $timeout
would also be inside an $apply
block.
请注意,我使用setTimeout,而不是$ timeout。 $ timeout也在$ apply块内。
#2
3
The idea was to use button to 'emulate' the file input; I achieved this using http://gregpike.net/demos/bootstrap-file-input/demo.html.
想法是使用按钮来“模拟”文件输入;我使用http://gregpike.net/demos/bootstrap-file-input/demo.html实现了这一点。
input#save-csv(type="file", title="Export to CSV", onchange="angular.element(this).scope().saveCSVFileChanged(this)")
#3
1
I just came across this problem and have written a drop in solution. You can write a custom directive composed of a container, a button, and an input element with type file. With CSS you then place the input over the custom button but with opacity 0. You set the containers height and width to exactly the offset width and height of the button and the input's height and width to 100% of the container.
我刚刚遇到了这个问题并写了一个解决方案。您可以编写由容器,按钮和类型为file的input元素组成的自定义指令。使用CSS,然后将输入放在自定义按钮上,但不透明度为0.您可以将容器的高度和宽度设置为按钮的偏移宽度和高度,输入的高度和宽度设置为容器的100%。
the directive
指令
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
})
}
};
});
a jade template if you are using jade
如果你正在使用玉石的玉石模板
div(class="file-upload-container")
button(class="file-upload-button") +
input#file-upload(class="file-upload-input", type='file', onchange="doSomethingWhenFileIsSelected()")
the same template in html if you are using html
如果你使用html,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>
the css
css
.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;
}