Javascript 角度文件上载指令不更新控制器模型
我试图遵循这一点,但无法让它工作 我的角度控制器正在记录指令中创建的模型的Javascript 角度文件上载指令不更新控制器模型,javascript,angularjs,angularjs-directive,angularjs-scope,Javascript,Angularjs,Angularjs Directive,Angularjs Scope,我试图遵循这一点,但无法让它工作 我的角度控制器正在记录指令中创建的模型的未定义的。 下面是我的教程作者创建的一个工作实例 问题是视图可以找到$scope.myFile,但控制器没有($scope.myFile是未定义的) 该视图显示{{myFile.name}(例如my image.jpg)。myFile变量是一个JS对象,包含选定文件上的数据。这个很好用。该指令似乎在为模型指定选定文件的值(从而在视图中正确显示该文件) 在控制器中,我只需记录$scope.myFile。这是从上面HTML中的
未定义的。
下面是我的教程作者创建的一个工作实例
问题是视图可以找到$scope.myFile
,但控制器没有($scope.myFile
是未定义的
)
该视图显示{{myFile.name}
(例如my image.jpg
)。myFile
变量是一个JS对象,包含选定文件上的数据。这个很好用。该指令似乎在为模型指定选定文件的值(从而在视图中正确显示该文件)
在控制器中,我只需记录$scope.myFile
。这是从上面HTML中的按钮调用的。
理想情况下,我会在这里将文件上载到服务器,但我不能,因为$scope.myFile
未定义
$scope.uploadDocs = function() {
var file = $scope.myFile;
console.log($scope.myFile);
};
有人能告诉我为什么视图会接收$scope.myFile
,但控制器会记录未定义的以查看$scope.myFile
?我在尝试从控制器访问指令变量时遇到了相同的问题。在我的情况下,我可以使控制器可以使用myFile
,但我必须从指令中将其分配给scope.$parent.$parent.myFile
。我不想为了访问变量而对祖先进行硬编码,所以我最终使用了一个服务在指令和控制器之间共享变量:
.factory('fileService', function() {
var files = [];
return files;
})
我的指令代码更改为使用服务,而不是教程中使用的attrs.fileModel
:
.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');
}
});
});
}
};
}])
然后,将fileService注入控制器后,我可以直接从fileService访问该文件:
$scope.uploadDocs = function() {
console.log(fileService);
};
我看过该教程,但选择使用此库,使文件上传无缝:
尝试以下解决方案:
HTML代码:
<div class="btn-header">
<label for="attachment" class="control-label">Attachment</label>
<div class="has-feedback">
<input type="file" id="fileUpload" name="attachment" ng-disabled="BRPTab.BRPTelePhonyandTestScipt.Checked"
class="form-control" data-ak-file-model="BRPTab.tutorial.attachment" />
<span class="form-control-feedback" aria-hidden="true"></span>
<div class="help-block with-errors"></div>
</div>
</div>
如果你们面临任何问题,请告诉我。试试下面的代码
<html>
<head>
<script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body ng-app = "myApp">
<div ng-controller = "myCtrl">
<input type = "file" file-model = "myFile"/>
<button ng-click = "uploadFile()">upload me</button>
</div>
<script>
var myApp = angular.module('myApp', []);
myApp.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(){
modelSetter(scope, element[0].files[0]);
});
});
}
};
}]);
myApp.service('fileUpload', ['$http', function ($http) {
this.uploadFileToUrl = function(file, uploadUrl){
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
})
.error(function(){
});
}
}]);
myApp.controller('myCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){
$scope.uploadFile = function(){
var file = $scope.myFile;
console.log('file is ' );
console.dir(file);
var uploadUrl = "/fileUpload";
fileUpload.uploadFileToUrl(file, uploadUrl);
};
}]);
</script>
</body>
</html>
上传我
var myApp=angular.module('myApp',[]);
myApp.directive('fileModel',['$parse',function($parse){
返回{
限制:“A”,
链接:函数(范围、元素、属性){
var model=$parse(attrs.fileModel);
var modelSetter=model.assign;
元素绑定('change',function()){
作用域$apply(函数(){
modelSetter(作用域,元素[0]。文件[0]);
});
});
}
};
}]);
myApp.service('fileUpload',['$http',函数($http){
this.uploadFileToUrl=函数(文件,uploadUrl){
var fd=新FormData();
fd.append('file',file);
$http.post(上传URL、fd、{
请求:angular.identity,
标题:{'Content-Type':未定义}
})
.success(函数(){
})
.错误(函数(){
});
}
}]);
myApp.controller('myCtrl',['$scope','fileUpload',函数($scope,fileUpload){
$scope.uploadFile=函数(){
var file=$scope.myFile;
log('file is');
console.dir(文件);
var uploadUrl=“/fileUpload”;
uploadFileToUrl(文件,uploadUrl);
};
}]);
这个问题可以在几个角度版本中看到,其中file object不能设置为scope变量。作为一种变通方法,将字段传递给控制器,使用此文件对象进行上载(不是从范围)
HTML表单
<form>
<div class="form-group">
<label for="myFileField">Select a file: </label>
<input type="file" file-model="myFile" /> <label>File Name:</label>
<input type="text" ng-model="filename"></input>
</div>
<button ng-click="uploadFile(myFile)" class="btn btn-primary">Upload File</button>
</form>
希望这能解决问题尝试将我的文件初始化为控制器的第一行:$scope.myFile={}代码>这主要是点问题,我对您提供的代码进行了修改,效果很好:今天遇到了这个问题。将“myFile”传递到像这样的uploadDocs(myFile)
函数中似乎可以做到这一点@akinwale为meI工作的解决方案与相同的JSFIDLE有完全相同的问题,出于某种原因,它在我的代码中不起作用,但在小提琴中可以很好地工作@Akinwale的解决方案对我很有效,但在挣扎了三个小时之后,我非常想知道为什么它不起作用!这个解决方法很好,但是理解这个问题对我来说很重要。当你使用ng annotate时,modelSetter也会遇到同样的问题,除非我使用服务来共享变量,否则modelSetter对我不起作用。我仍然非常想知道为什么Q中的教程可以很好地工作(对我也是如此)但是在我自己的代码中实现了它,它没有-我得到了与未定义$scope.myFile的OP相同的错误。尽管如此,这个解决方案还是有效的,而且很容易理解,因此格伦赢得了赏金。
AppService.factory("entityService", ["akFileUploaderService", function(akFileUploaderService) {
var saveTutorial = function(tutorial, url) {
return akFileUploaderService.saveModel(tutorial, url);
};
return {
saveTutorial: saveTutorial
};
}]);
(function() {
"use strict"
angular.module("akFileUploader", [])
.factory("akFileUploaderService", ["$q", "$http",
function($q, $http) {
var getModelAsFormData = function(data) {
var dataAsFormData = new FormData();
angular.forEach(data, function(value, key) {
dataAsFormData.append(key, value);
});
return dataAsFormData;
};
var saveModel = function(data, url) {
var deferred = $q.defer();
$http({
url: url,
method: "POST",
//data:
// {
// tutorial: getModelAsFormData(data),
// Object: Obj
// },
//params: Indata,
data: getModelAsFormData(data),
transformRequest: angular.identity,
headers: {
'Content-Type': undefined
}
}).success(function(result) {
deferred.resolve(result);
}).error(function(result, status) {
deferred.reject(status);
});
return deferred.promise;
};
return {
saveModel: saveModel
}
}
])
.directive("akFileModel", ["$parse",
function($parse) {
return {
restrict: "A",
link: function(scope, element, attrs) {
var model = $parse(attrs.akFileModel);
var modelSetter = model.assign;
element.bind("change", function() {
scope.$apply(function() {
modelSetter(scope, element[0].files[0]);
});
});
}
};
}
]);
})(window, document);
<html>
<head>
<script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body ng-app = "myApp">
<div ng-controller = "myCtrl">
<input type = "file" file-model = "myFile"/>
<button ng-click = "uploadFile()">upload me</button>
</div>
<script>
var myApp = angular.module('myApp', []);
myApp.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(){
modelSetter(scope, element[0].files[0]);
});
});
}
};
}]);
myApp.service('fileUpload', ['$http', function ($http) {
this.uploadFileToUrl = function(file, uploadUrl){
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
})
.error(function(){
});
}
}]);
myApp.controller('myCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){
$scope.uploadFile = function(){
var file = $scope.myFile;
console.log('file is ' );
console.dir(file);
var uploadUrl = "/fileUpload";
fileUpload.uploadFileToUrl(file, uploadUrl);
};
}]);
</script>
</body>
</html>
<form>
<div class="form-group">
<label for="myFileField">Select a file: </label>
<input type="file" file-model="myFile" /> <label>File Name:</label>
<input type="text" ng-model="filename"></input>
</div>
<button ng-click="uploadFile(myFile)" class="btn btn-primary">Upload File</button>
</form>
$scope.uploadFile = function (file1) {
var file = $scope.myFile; // this is undefined
console.log("My file =" +file1); // you get this
// Make http call to upload the file or make service call
}