Javascript 如何双向绑定到类型=";文件";使用ng模型输入?

Javascript 如何双向绑定到类型=";文件";使用ng模型输入?,javascript,angularjs,Javascript,Angularjs,基本上我想这样做: <input type="file" ng-model="variable_in_scope"> 当我拾取一个文件时,应将\u范围中的变量\u分配给拾取的文件对象。此外,如果在我的页面的任何其他地方更改了\u scope中的变量\u的值,它应该更新“选择文件”按钮旁边的文本,以指示所选文件已更改 对于任何其他类型的输入,这都是可行的 我不需要做任何花哨的事情,比如实际查看文件的内容。最终,我想发布它,但我发现你可以通过,而不需要将内容真正读入Javascri

基本上我想这样做:

<input type="file" ng-model="variable_in_scope">

当我拾取一个文件时,应将\u范围中的
变量\u分配给拾取的文件对象。此外,如果在我的页面的任何其他地方更改了\u scope
中的
变量\u的值,它应该更新“选择文件”按钮旁边的文本,以指示所选文件已更改

对于任何其他类型的输入,这都是可行的

我不需要做任何花哨的事情,比如实际查看文件的内容。最终,我想发布它,但我发现你可以通过,而不需要将内容真正读入Javascript

我还发现了关于使用angular拾取文件的其他问题,但没有一个问题有双向绑定解决方案。

关于另一个问题,提供了一种使用
ng model
实现这一点的方法,但由于该问题并不是专门关于双向绑定的(我的答案在那里很难找到),我将在这里重复:

app.directive('bindFile', [function () {
    return {
        require: "ngModel",
        restrict: 'A',
        link: function ($scope, el, attrs, ngModel) {
            el.bind('change', function (event) {
                ngModel.$setViewValue(event.target.files[0]);
                $scope.$apply();
            });

            $scope.$watch(function () {
                return ngModel.$viewValue;
            }, function (value) {
                if (!value) {
                    el.val("");
                }
            });
        }
    };
}]);

要使用它,只需将其添加到angular模块中,并在要使用它的文件选择器上包含一个
绑定文件
属性。

,但我使用了许多其他答案拼凑出了一个解决方案

app.directive('filePicker', filePicker);

filePicker.$inject = ['$log', '$document'];

function filePicker($log,$document) {

  var directive = {
    restrict: 'A',
    require: 'ngModel',
    scope: {
      ngModel: '='
    },
    link: _link
  };

  return directive;

  function _link(scope, elem, attrs, ngModel) {

    // check if valid input element
    if( elem[0].nodeName.toLowerCase() !== 'input' ) {
      $log.warn('filePicker:', 'The directive will work only for input element, actual element is a', elem[0].nodeName.toLowerCase());
      return;
    }

    // check if valid input type file
    if( attrs.type != 'file' ) {
      $log.warn('filePicker:', 'Expected input type file, received instead:', attrs.type, 'on element:', elem);
      return;
    }

    // listen for input change
    elem.on('change', function(e) {

      // get files
      var files = elem[0].files;

      // update model value
      scope.$apply(function() {
          attrs.multiple ? scope.ngModel = files : scope.ngModel = files[0];
      });
    });

    scope.$watch('ngModel', function() {
        if (!scope.ngModel)
            elem[0].value = ""; // clears all files; there's no way to remove only some
    });

  }

}
演示了如何使用指令实现到ng模型的自定义绑定。它允许访问文件的内容,因此如果需要该功能,可以将其添加回我的解决方案

但是,它的绑定存在一些问题。它将正确设置我的
变量\u在\u范围内的值,但是如果有其他东西绑定到
变量\u在\u范围内的值,它们将不会更新。这样,您就不需要处理这个
$setViewValue
业务了。就这么定了,忘了它吧

这让我走到了单程绑定的地步。但是,如果我在_scope
中将值设置为
variable _,则文件选择器仍然显示我选择了原始文件。在我的情况下,我真正想做的就是清除所选的文件。我发现并在
ngModel
上设置了一个
$watch
来触发它

如果您想以编程方式将文件设置为不同的值,祝您好运,因为。允许您清除
文件列表
,但不能添加任何内容。也许您可以创建一个新的
文件列表
,并将其分配给
。文件
,但粗略地看一下,我没有找到这样做的方法。

对我有帮助:

隐藏输入元素并显示:无;然后在输入元素顶部使用一个标签,并使用一个连接到范围变量的标签。看到很多这样的帖子。像这样:

<label for="idFileUpload" class="custom-file-upload">
    SelectFile
</label>
<input type="file" id="idFileUpload" nv-file-select uploader="uploader">
<label id="idSelectedFile">{{selectedFile}}</label>
<md-button id="idUploadBtn" md-no-ink class="md-primary settingsBtns" ng-click="uploader.uploadAll()" ng-disabled="!uploader.getNotUploadedItems().length">Upload</md-button>
在FileUploader触发的事件中,您可以获取输入元素的值。HTH

可能重复的
input[type="file"] {
    display: none;
}

.custom-file-upload {
    background-color: green;
    color: white;
    border: 1px solid #ccc;
    display: inline-block;
    padding: 6px 12px;
    cursor: pointer;
}