У меня есть рабочий пример с использованием стандартного Javascript, но я хотел бы сделать эту работу более естественной с помощью AngularJS.
В частности, мне нужно обновить span с именем файла, выбранного пользователем.
Вот что я реализовал с использованием собственного Javascript:
<span>
<input ng-model="uploadDownloads" type="file" style="visibility:hidden; width: 1px;" id=uploadDownloads name=uploadDownloads onchange="$(this).parent().find('span').html($(this).val().replace('C:\\fakepath\\', ''))" /> <!-- Chrome security returns 'C:\fakepath\' -->
<input class="btn btn-primary" type="button" value="choose file" onclick="$(this).parent().find('input[type=file]').click();"/> <!-- on button click fire the file click event -->
<span class="badge badge-important" ></span>
</span>
Функция filereader уже угловая:
$scope.add = function(valid){
if(valid){
$scope.data = 'none';
var f = document.getElementById('uploadDownloads').files[0];
var r = new FileReader();
r.onloadend = function(e){
$scope.data = e.target.result;
$scope.notPass = false;
$modalInstance.close({
'data':$scope.data,
'fileName':$scope.fileName,
'fileExplain':$scope.fileExplain
});
};
/*activate the onloadend to catch the file*/
r.readAsBinaryString(f);
} else {
$scope.notPass = true;
}
};
Проблема состоит в том, чтобы активировать onclick и onchange с помощью Angular вместо JavaScript, чтобы my <span>
обновлялся с выбранным именем файла.
Этот вопрос основывается на существующем вопросе и ответе. В частности, однако, я изменил код из этого ответа, чтобы разместить то, что, по-видимому, является конкретным вопросом здесь, а именно, как вы обновляете <span>
чтобы иметь имя файла, выбранное пользователем, таким образом, что идиоматический для angularjs.
Здесь код с рабочим образцом.
Здесь соответствующая часть html файла:
<body ng-controller="AppController">
<input ng-model="uploadDownloads" type="file" fd-input file-name="fileName"/>
<span class="badge badge-important">Output here: {{fileName}}</span>
</body>
Ключевым здесь является то, что у вас есть настраиваемая директива, называемая fd-input
которая имеет двустороннюю привязку к атрибуту, который он определяет, называемому file-name
. Вы можете передать одну из ваших переменных $scope
в этот атрибут, и директива привяжет к ней имя файла. Здесь контроллер и директива.
(function() {
'use strict';
angular.module('app', [])
.controller('AppController', AppController)
.directive('fdInput', fdInput);
function AppController($scope) {
$scope.fileName = '';
}
function fdInput() {
return {
scope: {
fileName: '='
},
link: function(scope, element, attrs) {
element.on('change', function(evt) {
var files = evt.target.files;
console.log(files[0].name);
console.log(files[0].size);
scope.fileName = files[0].name;
scope.$apply();
});
}
}
};
})();
Как упоминалось выше, директива берется непосредственно из другого ответа SO. Я изменил его, чтобы добавить область, которая выполняет двустороннюю привязку к атрибуту file-name
:
...
return {
scope: {
fileName: '='
},
...
Затем я назначаю files[0].name
для двусторонней привязки:
...
scope.fileName = files[0].name;
scope.$apply();
...
Оформить заказ codepen. Это должно сделать это. Вы можете просто использовать родительскую область в директиве, но это не очень хорошая идея, поскольку она ограничивает вас использованием этой директивы один раз для каждого контроллера. Кроме того, если вы хотите перечислить несколько файлов, вам придется обновить этот код, чтобы вернуть массив этих файлов.
Надеюсь, это поможет.
$scope
с модальной angular-ui. Ты почти там! :) Если вы не возражаете, отметьте этот ответ, чтобы он не отображался как неотвеченный, когда сообщество ищет ответы на вопросы. Удачи!