【问题标题】:Angularjs - ng-disabled doesn't work as expectedAngularjs - ng-disabled 无法按预期工作
【发布时间】:2014-09-08 11:38:25
【问题描述】:

在用户选择文件后,我正在尝试禁用文件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 范围。

secondControllerupload 是通用控制器,因此不继承自 firstController

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

【问题讨论】:

  • 不要使用表达式,只使用变量
  • 我认为文件输入不在fileInMemory所属的范围内。你能做一个演示吗?
  • @charlietfl 我也使用了该变量,但它不起作用。
  • @Alborz 我如何检查它们是否在同一范围内?当我将fileInMemory 的值输出到 HTML 时,它显示正确,值正确。
  • 您使用嵌套范围吗?使用 abject 而不是原始类型。

标签: javascript html angularjs


【解决方案1】:

您将不得不在此处利用$apply,因为它正在事件内部进行更改:

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

更新:针对导致问题的孤立范围,将fileInMemory 移至$rootScope

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

【讨论】:

  • 我用$scope.$apply 试过了,但还是不行。我认为元素上的directive 创建了自己的隔离范围。
  • @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 "controller as" syntax - clarification?

【讨论】:

    【解决方案3】:

    你试过这样吗

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

    这是一个工作示例demo

    【讨论】:

    • 我已经发布了演示链接,你能分享你的代码吗?可能是值不在正确的范围内?
    • 我添加了更多代码,我确实在另一个控制器中有一个控制器,并且变量由外部控制器操作。有问题吗?
    • 是的,如果你有嵌套控制器,你应该在变量之前使用控制器名称,例如 ctrl2.fileInMemory
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      尝试关注

      ng-disabled="fileInMemory"
      

      【讨论】:

        【解决方案6】:

        使用 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.
        • 如果可能的话,发布一个演示。
        【解决方案7】:

        你试过了吗:

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

        Working fiddle here

        【讨论】:

          【解决方案8】:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-12-10
            • 2018-10-27
            • 1970-01-01
            • 2013-05-14
            • 1970-01-01
            相关资源
            最近更新 更多