0

pluploadのディレクティブを作成しようとしています。一度に1ステップずつ実行するために、最初に、ディレクティブ(controllerおよびstd html)を使用せずにファイルのアップロードを機能させました。次に、ディレクティブを追加して、htmlを正しくレンダリングできるようにしました。残念ながら、pluploadバインディングはその後壊れました。

一見する、pluploadがバインドを行う前にディレクティブがレンダリングされていないように見えますが、コード内にログステートメントを追加すると、ディレクティブはハッシュを返し、すべてのhtml要素がDOM内に存在するように見えます。

これを機能させる方法について何かアイデアはありますか?

html

<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>

uploader.js

var uploader = angular.module('uploader', []);

uploader.directive('uploader', function () {
alert("in directive");
return  {
    restrict: 'E',
    scope: {
        url:'@'
    },
    templateUrl: "/assets/uploader.html"
}
});

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>

profile_photo_uploader.js

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();
};
4

1 に答える 1

0

これは、 2つのバージョンのディレクティブを使用したフィドルです。新しいスコープを作成することはありません。もう1つは、分離スコープを作成します。私が見つけたのは、ng-clickに{{}}を含めることはできないため、コンパイル関数を使用して、属性引数(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属性は必須ではありませんが、ディレクティブが呼び出すスコープメソッド(「upload」)が指示され、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())
        }
    }
});

上記のディレクティブは、新しいスコープ(分離スコープ)を作成します。このスコープは、通常、親/コントローラースコープから継承しないため、このスコープ(およびディレクティブのテンプレート)は、コントローラーの$ scopeで定義されたupload()関数にアクセスできません。「&」表記は、「デリゲート」uploadFn関数を作成するために使用されます。つまり、「uploadFn」が分離スコープ(つまり、ディレクティブのテンプレート)で使用されると、実際には親スコープで「upload」関数が呼び出されます。

さらに、アップロード関数が1つの引数urlを受け取るように指定します。ディレクティブのテンプレートでデリゲート関数を使用する場合、引数を渡すだけでは不十分です。つまり、これは機能しません:uploadFn('http:// ...')。代わりに、マップ/オブジェクトを使用して引数値を指定する必要があります。例:uploadFn({url:'http:// ...'})。

url: '@'属性ng-clickの値にsを含めることができるとは思わないため、分離スコープオブジェクトハッシュには含まれていません{{}}。これが、コンパイル関数を使用し、コンパイル関数の属性引数を介してurl属性の値を取得する理由です。url値がテンプレートの他の場所(など)でのみ使用された場合は<span>url = {{url}}</span>、「@」表記が使用されます。

テンプレートは、ng-click属性の値を削除するように変更されました。値は、コンパイル関数の属性に割り当てられます。

<button class="button small" ng-click>Upload File</button>
于 2013-01-18T19:11:09.693 に答える