用于`<input type ="file"/>`的ng-model(带指令DEMO)

End*_*ono 275 angularjs angularjs-ng-model angularjs-fileupload

我尝试在输入标签上使用ng-model和类型文件:

<input type="file" ng-model="vm.uploadme" />
Run Code Online (Sandbox Code Playgroud)

但是在选择文件后,在控制器中,$ scope.vm.uploadme仍未定义.

如何在控制器中获取所选文件?

End*_*ono 323

我用指令创建了一个解决方法:

.directive("fileread", [function () {
    return {
        scope: {
            fileread: "="
        },
        link: function (scope, element, attributes) {
            element.bind("change", function (changeEvent) {
                var reader = new FileReader();
                reader.onload = function (loadEvent) {
                    scope.$apply(function () {
                        scope.fileread = loadEvent.target.result;
                    });
                }
                reader.readAsDataURL(changeEvent.target.files[0]);
            });
        }
    }
}]);
Run Code Online (Sandbox Code Playgroud)

输入标签变为:

<input type="file" fileread="vm.uploadme" />
Run Code Online (Sandbox Code Playgroud)

或者,如果只需要文件定义:

.directive("fileread", [function () {
    return {
        scope: {
            fileread: "="
        },
        link: function (scope, element, attributes) {
            element.bind("change", function (changeEvent) {
                scope.$apply(function () {
                    scope.fileread = changeEvent.target.files[0];
                    // or all selected files:
                    // scope.fileread = changeEvent.target.files;
                });
            });
        }
    }
}]);
Run Code Online (Sandbox Code Playgroud)

  • 不要忘记$ scope.$ on('$ destory',function(){element.unbind("change");} (9认同)
  • 问题是该指令创建了一个childScope,并在该范围内设置了uploadme.原始(父)范围也有一个uploadme,它不受childScope的影响.我可以从任一范围更新HTML中的uploadme.有没有办法避免创建一个childScope? (4认同)
  • @AlexC很好的问题是关于ng-model不工作,而不是关于上传文件:)那时我不需要上传文件.但最近我学会了如何从这个[egghead.io教程](https://egghead.io/lessons/angularjs-file-uploads)上传文件. (4认同)
  • 我在img标签中使用uploadme作为src,所以我可以看到它是由指令设置的.但是,如果我尝试使用$ scope.uploadme从控制器中获取它,则它是"未定义的".不过,我可以从控制器设置uploadme.例如,$ scope.uploadme ="*"使图像消失. (3认同)
  • 我有一个问题....与普通的javascript和html相比,这不是太复杂吗?说真的,你真的需要了解AngularJS才能达到这个解决方案......而且似乎我可以用javascript事件做同样的事情.为什么选择Angular方式而不是简单的JS方式呢? (2认同)

Elm*_*mer 53

我使用这个指令:

angular.module('appFilereader', []).directive('appFilereader', function($q) {
    var slice = Array.prototype.slice;

    return {
        restrict: 'A',
        require: '?ngModel',
        link: function(scope, element, attrs, ngModel) {
                if (!ngModel) return;

                ngModel.$render = function() {};

                element.bind('change', function(e) {
                    var element = e.target;

                    $q.all(slice.call(element.files, 0).map(readFile))
                        .then(function(values) {
                            if (element.multiple) ngModel.$setViewValue(values);
                            else ngModel.$setViewValue(values.length ? values[0] : null);
                        });

                    function readFile(file) {
                        var deferred = $q.defer();

                        var reader = new FileReader();
                        reader.onload = function(e) {
                            deferred.resolve(e.target.result);
                        };
                        reader.onerror = function(e) {
                            deferred.reject(e);
                        };
                        reader.readAsDataURL(file);

                        return deferred.promise;
                    }

                }); //change

            } //link
    }; //return
});
Run Code Online (Sandbox Code Playgroud)

并像这样调用它:

<input type="file" ng-model="editItem._attachments_uri.image" accept="image/*" app-filereader />
Run Code Online (Sandbox Code Playgroud)

属性(editItem.editItem._attachments_uri.image)将填充您选择作为data-uri(!)的文件的内容.

请注意,此脚本不会上传任何内容.它只会使用data-uri(base64)编码文件的内容来填充模型.

在这里查看一个有效的演示:http: //plnkr.co/CMiHKv2BEidM9SShm9Vv

  • 看起来很有前途,请您解释一下代码背后的逻辑,并评论一下浏览器的兼容性(主要是IE和非fileAPI浏览器)? (4认同)

geo*_*awg 32

使用指令的工作演示 ng-model

如何让<input type="file">一起工作ng-model

核心ng-model指令不适用于<input type="file"开箱即用.

这个自定义指令启用ng-model并具有使额外的好处ng-change,ng-required以及ng-form指令一起工作<input type="file">.

angular.module("app",[]);

angular.module("app").directive("selectNgFiles", function() {
  return {
    require: "ngModel",
    link: function postLink(scope,elem,attrs,ngModel) {
      elem.on("change", function(e) {
        var files = elem[0].files;
        ngModel.$setViewValue(files);
      })
    }
  }
});
Run Code Online (Sandbox Code Playgroud)
<script src="//unpkg.com/angular/angular.js"></script>
  <body ng-app="app">
    <h1>AngularJS Input `type=file` Demo</h1>
    
    <input type="file" select-ng-files ng-model="fileArray" multiple>

    <code><table ng-show="fileArray.length">
    <tr><td>Name</td><td>Date</td><td>Size</td><td>Type</td><tr>
    <tr ng-repeat="file in fileArray">
      <td>{{file.name}}</td>
      <td>{{file.lastModified | date  : 'MMMdd,yyyy'}}</td>
      <td>{{file.size}}</td>
      <td>{{file.type}}</td>
    </tr>
    </table></code>
    
  </body>
Run Code Online (Sandbox Code Playgroud)


Per*_*son 27

这是@ endy-tjahjono解决方案的附录.

我最终无法从范围中获取uploadme的值.即使HTML中的uploadme被指令明显更新,我仍然无法通过$ scope.uploadme访问其值.不过,我能够从范围设置其值.神秘,对......

事实证明,指令创建了子范围,子范围有自己的uploadme.

解决方案是使用对象而不是基元来保存uploadme的值.

在控制器中我有:

$scope.uploadme = {};
$scope.uploadme.src = "";
Run Code Online (Sandbox Code Playgroud)

在HTML中:

 <input type="file" fileread="uploadme.src"/>
 <input type="text" ng-model="uploadme.src"/>
Run Code Online (Sandbox Code Playgroud)

指令没有变化.

现在,它都像预期的那样工作.我可以使用$ scope.uploadme从我的控制器获取uploadme.src的值.

  • 也许这与您的问题类似?http://egghead.io/lessons/angularjs-the-dot (4认同)

yoz*_*ama 9

大家好我创建一个指令并在凉亭上注册.

这个lib将帮助您建模输入文件,不仅返回文件数据,还包括文件dataurl或base 64.

{
    "lastModified": 1438583972000,
    "lastModifiedDate": "2015-08-03T06:39:32.000Z",
    "name": "gitignore_global.txt",
    "size": 236,
    "type": "text/plain",
    "data": "data:text/plain;base64,DQojaWdub3JlIHRodW1ibmFpbHMgY3JlYXRlZCBieSB3aW5kb3dz…xoDQoqLmJhaw0KKi5jYWNoZQ0KKi5pbGsNCioubG9nDQoqLmRsbA0KKi5saWINCiouc2JyDQo="
}
Run Code Online (Sandbox Code Playgroud)

https://github.com/mistralworks/ng-file-model/

希望能帮到你