Я пытаюсь отключить тэг input
файла после того, как пользователь выбрал файл.
HTML:
<div ng-controller='firstController'>
<div ng-controller='secondController'>
<input type="file" name="file" upload class="theFileInput" ng-disabled="fileInMemory">
</div>
</div>
JS, первый контроллер:
$scope.fileInMemory = false; // tracks if user selected a file for upload, but didn't upload it
$rootScope.$on('fileAdded', function () {
$scope.fileInMemory = true;
console.log($scope.fileInMemory);
});
upload
- это директива.
При загрузке страницы ng-disabled
имеет false
, как и должно быть, когда fileInMemory
изменен, тэг input
все еще не отключен. console.log
показывает, что значение fileInMemory
меняется так, как должно быть.
Что я пробовал до сих пор
<input type="file" name="file" class="theFileInput" ng-disabled="'fileInMemory'">
Просто отключает поле сразу, когда fileInMemory
является ложным.
<input type="file" name="file" class="theFileInput" ng-disabled="fileInMemory == 'true'">
Не работает.
<input type="file" name="file" class="theFileInput" ng-disabled="{{fileInMemory}}">
Все еще не работает.
Каков наилучший способ отключить тег input
?
Обнаружена проблема
Похоже, проблема здесь - области.
У меня firstController
с его "областью" внутри secondController
с ее "областью" и директивой input
тега upload
, которая, по-видимому, создает свою собственную область видимости и не видит область firstController
.
secondController
и upload
являются общими контроллерами и поэтому не наследуются от firstController
.
Я думаю, что лучшим решением является добавление некоторого общего обработчика в secondController
, который на основе дополнительного атрибута в поле input
отключит его при необходимости.
Вам придется использовать $apply
здесь, потому что он изменяется внутри события:
$scope.fileInMemory = false;
$rootScope.$on('fileAdded', function () {
$scope.$apply(function() {
$scope.fileInMemory = true;
console.log($scope.fileInMemory);
});
});
UPDATE: в ответ на проблемы с изолированной областью, переместите fileInMemory
в $rootScope
:
$rootScope.fileInMemory = false;
$rootScope.$on('fileAdded', function () {
$rootScope.$apply(function() {
$rootScope.fileInMemory = true;
console.log($scope.fileInMemory);
});
});
$scope.$apply
но это все еще не работает. Я думаю, что directive
об элементе создает свою изолированную область видимости.
$rootScope
вместо $scope
.
Если проблема связана с областями, попробуйте использовать синтаксис "controller as":
<div ng-controller='firstController as first'>
<div ng-controller='secondController as second'>
<input type="file" name="file" upload class="theFileInput" ng-disabled="first.fileInMemory">
</div>
</div>
Вкратце, каждый ngController
создает новую дочернюю область. Объем, созданный secondController
, уменьшает значение fileInMemory
от firstController
. Из-за этого изменение не распространяется, и его значение блокируется на false
. Этого можно легко избежать, используя синтаксис controllerAs
.
Вы так пробовали
<input type="file" name="file" class="theFileInput" ng-disabled="fileInMemory">
вот рабочий пример demo
Вы пробовали это:
HTML:
<div ng-controller='firstController'>
<div ng-controller='secondController'>
<input type="file" name="file" upload class="theFileInput" ng-disabled="fileInMemory.disabled">
</div>
</div>
Контроллер:
$scope.fileInMemory = { disabled: false };
$rootScope.$on('fileAdded', function () {
$scope.fileInMemory.disabled = true;
console.log($scope.fileInMemory);
});
Использовать abject вместо примитивного типа.
В первом контроллере:
$scope.model = {};
$scope.model.fileInMemory = false;
$rootScope.$on('fileAdded', function () {
$scope.model.fileInMemory = true;
console.log($scope.model.fileInMemory);
});
<div ng-controller='firstController'>
<div ng-controller='secondController'>
<input type="file" name="file" class="theFileInput" ng-disabled="model.fileInMemory">
</div>
</div>
firstController.model.fileInMemory
.
Попробуйте выполнить
ng-disabled="fileInMemory"
Ваша модель изменяется на консоли, но не на представлениях, потому что это изменение происходит за пределами приложения angular. Чтобы исправить это, нужно называть $apply на $rootScope, чтобы убедиться, что представления обновлены для этого события, вызываемого извне angular области приложения.
// Something like this
$rootScope.$apply(function() {
$rootScope.fileInMemory = true;
// Now it'll be changed in views too
});