Angularjs - ng-disabled无法按预期工作

时间:2022-08-22 17:17:17

I am trying to disable file input tag, after user selected a file.

我试图在用户选择文件后禁用文件输入标记。

HTML:

HTML:

<div ng-controller='firstController'>
    <div ng-controller='secondController'>
      <input type="file" name="file" upload class="theFileInput" ng-disabled="fileInMemory">
    </div>
</div>

JS, first controller:

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 is a directive.

upload是一个指令。

On page load, ng-disabled has false as it should, when fileInMemory is changed, input tag still not being disabled. console.log shows that the value of fileInMemory is changing as it should.

在页面加载时,ng-disabled具有错误,当fileInMemory更改时,输入标记仍未被禁用。 console.log显示fileInMemory的值正在改变。

What i tried so far

到目前为止我尝试了什么

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

Just disables the field right away, when fileInMemory is falsy.

当fileInMemory是假的时候,只需立即禁用该字段。

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

Doesn't work.

不起作用。

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

Still doesn't work.

仍然无法正常工作。

What is the best way to disable an input tag?

禁用输入标记的最佳方法是什么?

Found the issue

发现了这个问题

It looks like the issue here is scopes. I have firstController with its' scope, inside it secondController with its' scope, and on the input tag upload directive, which apparently creates its' own scope and doesn't see firstController scope.

看起来这里的问题是范围。我有firstController的'scope,在其内部的secondController及其'范围,以及输入标签上传指令,它显然创建了它自己的范围,并没有看到firstController范围。

secondController and upload are general controllers and therefore don't inherit from firstController.

secondController和upload是通用控制器,因此不从firstController继承。

I guess my best solution is to add some general handler in secondController, which based on additional attribute on input field will disable the it when needed.

我想我最好的解决方案是在secondController中添加一些通用处理程序,它基于输入字段上的附加属性将在需要时禁用它。

8 个解决方案

#1


5  

You're going to have to leverage $apply here because it's being changed inside of the event:

你将不得不在这里利用$ apply,因为它在事件中被改变了:

$scope.fileInMemory = false;
$rootScope.$on('fileAdded', function () {
    $scope.$apply(function() {
        $scope.fileInMemory = true;
        console.log($scope.fileInMemory);
    });
});

UPDATE: in response to an isolated-scope causing issues, move fileInMemory to the $rootScope:

更新:响应隔离范围导致问题,将fileInMemory移动到$ rootScope:

$rootScope.fileInMemory = false;
$rootScope.$on('fileAdded', function () {
    $rootScope.$apply(function() {
        $rootScope.fileInMemory = true;
        console.log($scope.fileInMemory);
    });
});

#2


2  

If the problem is with scopes, try using "controller as" syntax:

如果问题出在范围内,请尝试使用“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>

Link: AngularJs "controller as" syntax - clarification?

链接:AngularJs“控制器为”语法 - 澄清?

#3


1  

did you tried like this

你有没有试过这样的

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

here is a working example demo

这是一个工作示例演示

#4


1  

Briefly, each ngController creates a new child scope. The scope created by secondController shadows the value of fileInMemory from firstController. Because of this, the change doesn't propagate and its value is locked to false. This can easily be avoided by using controllerAs syntax.

简而言之,每个ngController都会创建一个新的子范围。 secondController创建的作用域从firstController隐藏fileInMemory的值。因此,更改不会传播,其值将被锁定为false。使用controllerAs语法可以轻松避免这种情况。

#5


0  

Try following

试试以下

ng-disabled="fileInMemory"

#6


0  

Use abject instead of primitive type.

使用abject而不是基本类型。

In the first controller:

在第一个控制器中:

$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>

#7


0  

did you try this:

你试过这个:

HTML:

HTML:

<div ng-controller='firstController'>
    <div ng-controller='secondController'>
      <input type="file" name="file" upload class="theFileInput" ng-disabled="fileInMemory.disabled">
    </div>
</div>

Controller:

控制器:

$scope.fileInMemory = { disabled: false }; 

$rootScope.$on('fileAdded', function () {
     $scope.fileInMemory.disabled = true;
     console.log($scope.fileInMemory);
});

Working fiddle here

在这里工作小提琴

#8


-1  

Your model is being changed on the console but not in views because this change is happening outside of angular app. The way to fix it is to call $apply on $rootScope to ensure that the views are updated of this event being called from outside angular app scope.

您的模型正在控制台上更改,但在视图中没有更改,因为此更改发生在角度应用程序之外。修复它的方法是在$ rootScope上调用$ apply以确保从外部角度应用程序范围调用此事件的视图已更新。

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

#1


5  

You're going to have to leverage $apply here because it's being changed inside of the event:

你将不得不在这里利用$ apply,因为它在事件中被改变了:

$scope.fileInMemory = false;
$rootScope.$on('fileAdded', function () {
    $scope.$apply(function() {
        $scope.fileInMemory = true;
        console.log($scope.fileInMemory);
    });
});

UPDATE: in response to an isolated-scope causing issues, move fileInMemory to the $rootScope:

更新:响应隔离范围导致问题,将fileInMemory移动到$ rootScope:

$rootScope.fileInMemory = false;
$rootScope.$on('fileAdded', function () {
    $rootScope.$apply(function() {
        $rootScope.fileInMemory = true;
        console.log($scope.fileInMemory);
    });
});

#2


2  

If the problem is with scopes, try using "controller as" syntax:

如果问题出在范围内,请尝试使用“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>

Link: AngularJs "controller as" syntax - clarification?

链接:AngularJs“控制器为”语法 - 澄清?

#3


1  

did you tried like this

你有没有试过这样的

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

here is a working example demo

这是一个工作示例演示

#4


1  

Briefly, each ngController creates a new child scope. The scope created by secondController shadows the value of fileInMemory from firstController. Because of this, the change doesn't propagate and its value is locked to false. This can easily be avoided by using controllerAs syntax.

简而言之,每个ngController都会创建一个新的子范围。 secondController创建的作用域从firstController隐藏fileInMemory的值。因此,更改不会传播,其值将被锁定为false。使用controllerAs语法可以轻松避免这种情况。

#5


0  

Try following

试试以下

ng-disabled="fileInMemory"

#6


0  

Use abject instead of primitive type.

使用abject而不是基本类型。

In the first controller:

在第一个控制器中:

$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>

#7


0  

did you try this:

你试过这个:

HTML:

HTML:

<div ng-controller='firstController'>
    <div ng-controller='secondController'>
      <input type="file" name="file" upload class="theFileInput" ng-disabled="fileInMemory.disabled">
    </div>
</div>

Controller:

控制器:

$scope.fileInMemory = { disabled: false }; 

$rootScope.$on('fileAdded', function () {
     $scope.fileInMemory.disabled = true;
     console.log($scope.fileInMemory);
});

Working fiddle here

在这里工作小提琴

#8


-1  

Your model is being changed on the console but not in views because this change is happening outside of angular app. The way to fix it is to call $apply on $rootScope to ensure that the views are updated of this event being called from outside angular app scope.

您的模型正在控制台上更改,但在视图中没有更改,因为此更改发生在角度应用程序之外。修复它的方法是在$ rootScope上调用$ apply以确保从外部角度应用程序范围调用此事件的视图已更新。

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