Angularjs - ng-disabled не работает должным образом

9

Я пытаюсь отключить тэг 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 отключит его при необходимости.

  • 1
    не используйте выражение, только переменную
  • 0
    Я думаю, что входной файл находится не в той области, к которой принадлежит fileInMemory. Вы можете сделать демо?
Показать ещё 5 комментариев

8 ответов

5
Лучший ответ

Вам придется использовать $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);
    });
});
  • 0
    Я попробовал это с $scope.$apply но это все еще не работает. Я думаю, что directive об элементе создает свою изолированную область видимости.
  • 0
    @Neara, исправление будет в том, чтобы переместить переменную в $rootScope вместо $scope .
2

Если проблема связана с областями, попробуйте использовать синтаксис "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>

Ссылка: AngularJs "контроллер как" синтаксис - уточнение?

1

Вкратце, каждый ngController создает новую дочернюю область. Объем, созданный secondController, уменьшает значение fileInMemory от firstController. Из-за этого изменение не распространяется, и его значение блокируется на false. Этого можно легко избежать, используя синтаксис controllerAs.

1

Вы так пробовали

<input type="file" name="file" class="theFileInput" ng-disabled="fileInMemory">

вот рабочий пример demo

  • 0
    да, я сделал, это не работает. супер расстраивает = \
  • 0
    Я разместил демонстрационную ссылку, можете поделиться своим кодом? может быть значение не в нужной области?
Показать ещё 2 комментария
0

Вы пробовали это:

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);
});

Рабочая скрипка здесь

0

Использовать 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>
  • 0
    Я попробовал это, это все еще не работает. Я также попытался сначала ссылаться на контроллер: firstController.model.fileInMemory .
  • 0
    опубликуйте демо, если это возможно.
0

Попробуйте выполнить

ng-disabled="fileInMemory"
-1

Ваша модель изменяется на консоли, но не на представлениях, потому что это изменение происходит за пределами приложения angular. Чтобы исправить это, нужно называть $apply на $rootScope, чтобы убедиться, что представления обновлены для этого события, вызываемого извне angular области приложения.

// Something like this
$rootScope.$apply(function() {
  $rootScope.fileInMemory = true;
  // Now it'll be changed in views too
});

Ещё вопросы

Сообщество Overcoder
Наверх
Меню