角度文件上传指令不更新控制器模型 [英] Angular File Upload directive not updating controller model

查看:22
本文介绍了角度文件上传指令不更新控制器模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试遵循此[教程],但可以'让它正常工作.

我的 Angular 控制器正在为在我的指令中创建的模型记录 undefined.这是一个 [JSFiddle] 它的工作创建了我的教程作者.

问题是视图可以找到 $scope.myFile 而控制器却找不到($scope.myFileundefined).

视图显示{{ myFile.name }}(作为示例my-image.jpg).myFile 变量是一个包含所选文件数据的 JS 对象.这工作正常.该指令似乎正在为模型分配所选文件的值(从而在视图中正确显示).

<button ng-click="uploadDocs()">点击</button>

这是我从这个[教程]中得到的指令.

由于输入类型 file 不能使用 ng-model,该指令将模型设置为与 file 输入相关联,每次文件触发 change 事件时分配给它.

directive('fileModel', ['$解析',函数($解析){返回 {限制:'A',链接:函数(范围,元素,属性){var 模型 = $parse(attrs.fileModel);var modelSetter = model.assign;element.bind('change', function(){范围.$应用(函数(){如果(元素 [0].files.length > 1){模型设置器(范围,元素[0].文件);}别的 {模型设置器(范围,元素[0].文件[0]);}});});}};}]).

在控制器中,我只记录 $scope.myFile.这是从上面 HTML 中的按钮调用的.理想情况下,我会将文件上传到此处的服务器,但我不能,因为 $scope.myFile 未定义.

$scope.uploadDocs = function() {var 文件 = $scope.myFile;console.log($scope.myFile);};

谁能告诉我为什么视图会收到 $scope.myFile 但控制器记录 undefined$scope.myFile?

解决方案

我在尝试从控制器访问指令的变量时遇到了同样的问题.就我而言,我可以使 myFile 可用于控制器,但我必须从指令中将其分配给 scope.$parent.$parent.myFile.我不想为了访问变量而在祖先的深度进行硬编码,所以我最终使用了一个服务来在指令和控制器之间共享变量:

.factory('fileService', function() {var 文件 = [];返回文件;})

我的指令代码更改为使用服务而不是教程中使用的 attrs.fileModel:

.directive('fileModel', ['$parse', 'fileService', function ($parse, fileService) {返回 {限制:'A',链接:函数(范围,元素){element.bind('change', function(){范围.$应用(函数(){如果(元素[0].文件!=未定义){fileService.push(element[0].files[0]);console.log('用文件申请的指令');}});});}};}])

然后,在将 fileService 注入控制器后,我可以直接从 fileService 访问文件:

$scope.uploadDocs = function() {控制台日志(文件服务);};

I am attempting to follow this [tutorial] but can't get it working.

My Angular controller is logging undefined for a model created in my directive. Here is a [JSFiddle] of it working created my author of tutorial.

The problem is the view can find $scope.myFile and but controller does not ($scope.myFile is undefined).

The view displays {{ myFile.name }} (as just example my-image.jpg). The myFile variable is a JS object containing data on selected file. This works fine. The directive seems to be assigning the model the value of selected file (and thus displays it correctly in view).

<input file-model="myFile" type="file"/ >
<div class="label label-info">
  {{ myFile.name }}
</div>
<button ng-click="uploadDocs()">Click</button>

Here is the directive I got from this [tutorial].

Since input type file can't use ng-model, this directive sets up the model to be associated with an file input, assigning to it every time the file fires change event.

directive('fileModel', [
  '$parse',
    function ($parse) {
      return {
        restrict: 'A',
        link: function(scope, element, attrs) {
          var model = $parse(attrs.fileModel);
          var modelSetter = model.assign;

          element.bind('change', function(){
            scope.$apply(function(){
              if (element[0].files.length > 1) {
                modelSetter(scope, element[0].files);
              }
              else {
                modelSetter(scope, element[0].files[0]);
              }
            });
          });
        }
      };
    }
  ]).

In the controller I just log $scope.myFile. This is called from the button in the HTML above. Ideally, I'd be uploading the files to server here, but I can't because $scope.myFile is undefined.

$scope.uploadDocs = function() {
  var file = $scope.myFile;
  console.log($scope.myFile);
};

Can someone tell me why the view would be recieving $scope.myFile but the controller logs undefined for $scope.myFile?

解决方案

I ran into the same problem when trying to access a directive's variable from the controller. In my case I could make myFile available to the controller, but I had to assign it to scope.$parent.$parent.myFile from within the directive. I didn't want to hard code in a depth of ancestry in order to access the variable, so I ended up using a service to share the variable between directive and controller:

.factory('fileService', function() {
    var files = [];
    return files;
})

My directive code changed to use the service instead of attrs.fileModel that was used in the tutorial:

.directive('fileModel', ['$parse', 'fileService', function ($parse, fileService) {
    return {
        restrict: 'A',
        link: function(scope, element) {
            element.bind('change', function(){
                scope.$apply(function(){
                    if (element[0].files != undefined) {
                        fileService.push(element[0].files[0]);
                        console.log('directive applying with file');
                    }
                });
            });
        }
    };
}])

Then, after injecting fileService into the controller I could access the file directly from fileService:

$scope.uploadDocs = function() {
    console.log(fileService);
};

这篇关于角度文件上传指令不更新控制器模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆