使用AngularJS实现<input type="file">中的条件“多个”属性

13

我需要一个上传表单字段,允许用户选择一个或多个文件。

我知道我可以做一些像这样的事情:

<input type="file" multiple ng-if="allow_multiple">
<input type="file" ng-if="!allow_multiple">

但是,我们知道那并不理想。

我尝试过

<input type="file" ng-multiple="allow_multiple">

但是那样行不通。

似乎 AngularJS 没有 ngMultiple 指令,但是每个人都在使用它(或者我漏掉了什么?)

无论如何,最好的实现方式是什么?

编辑:从目前为止的回答来看,似乎没有很好的方法来解决这个问题。 我在他们的跟踪器上开了一个问题,让我们看看会得到什么 :-) https://github.com/angular/angular.js/issues/7714


你考虑过使用ngUpload吗?它具有多个作为布尔选项的功能。 - Dalorzo
ng-multiple仅适用于选择(select)。 - Fals
@Dalorzo,你是指这个,对吗?https://github.com/twilson63/ngUpload。我会看一下的。 - Tony Lâmpada
@Fals,你知道在官方文档中哪里可以找到(用于<select>的ng-multiple)吗? - Tony Lâmpada
你可以尝试这个:https://github.com/danialfarid/angular-file-upload - Dalorzo
8个回答

7

我因Angular 2遇到了同样的问题来到这个页面

最终修复方式如下:

<input type="file" 
    [accept]="extAccepts" 
    [multiple]="(maxFiles > 1)" />

注意:文件类型(extAccepts)和最大文件数(maxFiles)均从用户组件的@input()中读取。
希望这对某些人有所帮助!

4
最简单的方法是编写自己的ngMultiple指令。
HTML(相关):
<label><input type="checkbox" ng-model="allowMultiple"> Allow multiple</label>
<hr>
<input
  type="file"
  class="hide"
  accept="image/*"
  ng-multiple="allowMultiple">

JS:

angular
    .module('app', [])
    .controller('appCtrl', function($scope) {
        $scope.allowMultiple = false;
    })
    .directive('ngMultiple', function () {
        return {
            restrict: 'A',
            scope: {
                ngMultiple: '='
            },
            link: function (scope, element) {
                var unwatch = scope.$watch('ngMultiple', function (newValue) {
                    if(newValue) {
                        element.attr('multiple', 'multiple');
                    } else {
                        element.removeAttr('multiple');
                    }
                });
            }
        };
    });

Plunker


2

除了难以实现之外,还存在这样的问题:有些浏览器不会评估multiple="false"(例如对于文件输入,Safari 8就是如此)。因此,必须有条件地编写多个属性。

我建议您将HTML代码包含在指令中,并在指令内有条件地应用属性,如下所示:

var input = elem.find('input');
if(condition)
  input.attr('multiple', 'true');

条件可以是任何指令属性。


1
请使用ng-attr-进行尝试。
 ng-attr-class="{{someBoolean && 'class-when-true' || 'class-when-false' }}"

如果您在任何属性前加上ng-attr-,编译器将会删除该前缀,并将该属性添加到其值与原始属性值中的angular表达式结果绑定。

3
谢谢,我不知道 ng-attr。现在这很奇怪,看:我尝试在我的<input>上添加 ng-attr-multiple="{{allow_multiple}}"。它对它没有影响,无论 allow_multiple 的值是什么。 现在,如果我添加 ng-attr-bolinha="{{allow_multiple}}",那么它会在输入框上添加一个属性 bolinha="false"bolinha="true"。 但是,即使它添加了 multiple="false",浏览器也不会将“false”属性视为重要,只要“multiple”存在,它仍然允许选择多个文件。嗯,我感觉应该更容易些。我要去问题跟踪器了... - Tony Lâmpada

0

很抱歉我在手机上回答,所以回答比较简短。

我会隐藏两个不同的文件输入框,一个带有 multiple 属性,另一个没有。您可以使用 ng-if 指令来实现。

编辑:非常抱歉,似乎您不想以这种方式做,尽管它完全有效。但是,您可以编写自己的指令来完成它,这非常简单。


0

谢谢Wilson。这解决了问题,但不完全是我要找的。这与使用ng-if没有什么区别(我必须声明两个输入)。 - Tony Lâmpada

0
另一个想法是使用ngShow/ngHide来实现。在这个演示例子中,输入文件基于参数的显示/隐藏,并有一个指令来获取输入值并将其设置为$scope参数。

使用ngShow + 指令的演示


谢谢Wilson。这解决了问题,但不完全是我要找的。这与使用ng-if没有什么区别(我必须声明两个输入)。 - Tony Lâmpada

0
解决方案非常简单,因为您正在使用指令或组件 - 只需在正确的时刻操作DOM即可。在这里看一眼:
app.component('myComponent', {
    templateUrl: 'tmpl.html',
    bindings: {
        str: '@'
    },
    controller: function ($element) {
        this.$postLink = function () {
            $element.find('input').attr('multiple', 'multiple');
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接