我正在尝试为plupload创建一个指令。为了一步一步,我首先让文件上传工作而不使用指令(controller和std html)。然后我添加了指令并成功获取了html以正确呈现。不幸的是,plupload绑定然后破了。
乍一看,似乎指令在plupload执行绑定之前没有呈现,但是如果我在代码中添加日志语句,则该指令会返回哈希并且所有html元素看起来都是存在于DOM中。
关于如何使这项工作的任何想法?
<div ng-controller="ProfilePhotoUploader">
This does not work
<uploader url="<%= profile_image_uploader_path %>"></uploader>
This works
<div id="profile-image-container">
<div id="select-file">Select File</div>
<div id="drop-area">Drop file here</div>
<button class="button small" ng-click="upload('<%= profile_image_uploader_path %>')">Upload File</button>
</div>
</div>
var uploader = angular.module('uploader', []);
uploader.directive('uploader', function () {
alert("in directive");
return {
restrict: 'E',
scope: {
url:'@'
},
templateUrl: "/assets/uploader.html"
}
});
<div id="profile-image-container">
<div id="select-file">Select File</div>
<div id="drop-area">Drop file here</div>
<button class="button small" ng-click="upload('{{url}}')">Upload File</button>
</div>
var ProfilePhotoUploader = function ($scope) {
console.log($("uploader"));
$scope.uploader = new plupload.Uploader({
runtimes: "html5",
browse_button: 'select-file',
max_file_size: '10mb',
container: "profile-image-container",
drop_element: "drop-area",
multipart: true,
multipart_params : {
authenticity_token: $('meta[name="csrf-token"]').attr('content'),
_method: 'PUT'
},
filters: [
{title: "Image Files", extensions: "jpg,jpeg,png"}
]
});
$scope.upload = function(url) {
$scope.uploader.settings.url = url;
$scope.uploader.start();
};
$scope.uploader.init();
};
答案 0 :(得分:0)
这是一个带有两个版本指令的fiddle。一个人没有创建新的范围。另一个创建了隔离范围。我发现ng-click不能包含{{}},因此我们需要使用编译函数通过attributes参数(tAttrs)将URL字符串输入模板。
没有新范围。 HTML:
<uploader url="http://someplace.com/pic.jpg" upload-fn="upload"></uploader>
指令:
myApp.directive('uploader', function () {
return {
restrict: 'E',
templateUrl: "/assets/uploader.html",
compile: function (tElement, tAttrs) {
var buttonElement = tElement.find('button')
buttonElement.attr('ng-click', tAttrs.uploadFn + "('" + tAttrs.url + "')")
console.log(tElement.html())
}
}
});
上面,该指令使用与控制器相同的作用域,因此ng-click属性的值设置为调用HTML中的upload-fn属性定义的函数。
upload-fn属性不是必需的,但它确实使指令更具可重用性,因为该指令被告知要调用的范围方法 - “上传” - 因此可以在HTML中轻松更改。如果可重用性不是问题,那么这是更简单的替代方案:
HTML:
<uploader url="http://someplace.com/pic.jpg"></uploader>
指令变更:
buttonElement.attr('ng-click', "upload('" + tAttrs.url + "')")
隔离范围。 HTML:
<uploader-isolate url="http://someplace.com/pic.jpg" upload-fn="upload(url)">
</uploader-isolate>
指令:
myApp.directive('uploaderIsolate', function () {
return {
restrict: 'E',
scope: {
uploadFn: '&'
},
templateUrl: "/assets/uploader.html",
compile: function (tElement, tAttrs) {
var buttonElement = tElement.find('button')
buttonElement.attr('ng-click', "uploadFn({url:'" + tAttrs.url + "'})")
console.log(tElement.html())
}
}
});
在上面,该指令创建了一个新范围 - isolate 范围。此范围不是从父/控制器范围原型继承,因此它(和指令的模板)无权访问控制器$ scope上定义的upload()函数。 '&amp;'表示法用于创建“委托”uploadFn函数。这意味着当在隔离范围中使用“uploadFn”时(即在指令的模板中),它实际上将在父范围上调用“upload”函数。
此外,我们指定upload函数采用一个参数 url 。在委托模板中使用委托函数时,我们不能只传递参数。即,这不起作用:uploadFn('http:// ...')。相反,我们需要使用map / object来指定任何参数值。例如,uploadFn({url:'http:// ...'})。
隔离范围对象哈希不包含url: '@'
,因为我认为属性ng-click的值不能包含{{}}
。这就是我们使用编译函数并通过编译函数的属性参数获取url属性值的原因。如果网址值仅在模板的其他位置使用,例如<span>url = {{url}}</span>
,则会使用“@”表示法。
更改模板以删除ng-click属性的值。该值将分配给编译函数中的属性。
<button class="button small" ng-click>Upload File</button>