0

私はこの素敵な Ember.js ミックスインを使用しています: https://github.com/Wildhoney/EmberDropletを使用して、ドラッグ アンド ドロップを使用して画像をアップロードしましたが、見事に機能しています。

唯一の問題は、アップロードされた画像をビューに追加する方法がわからないことです。モデルは Rails API で適切に更新されていますが、実際にページ全体を更新するまでは、Ember でモデルを更新する方法がわかりません。

ここに私のコードのいくつかのスニペットがあります:

router.js.coffee

App.Router.map ->
  @resource('site', { path: '/' }, ->
    @resource('media')
  )

routes.js.coffee

App.MediaRoute = Ember.Route.extend
  model: (params)->
    return App.Media.find()

media.handlebars

<div class="row">

    <div id="media-container" class="large-12">
        <div class="row">
        {{#each media in model}}
            <div class="large-4 columns">
                <a class="th" {{bind-attr href='media.url'}}>
                    <img {{bind-attr src='media.thumb'}}>
                </a>
            </div>
        {{else}}
            <div class="large-12">
                <p>Sorry, no images to display.</p>
            </div>
        {{/each}}
        </div>
    </div><!-- /#media-container -->

</div><!-- /.row -->

<div class="row">

    <div id="media-upload" class="large-12">
        <div class="buttons">
            <button class="btn" {{action "uploadAllFiles"}}>Upload All</button>
            <button class="btn" {{action "clearAllFiles"}}>Clear</button>
        </div>

        {{#if uploadStatus.uploading}}
            <h3 class="uploading-percentage">Uploaded Percentage: {{uploadStatus.percentComplete}}%</h3>
        {{/if}}

        {{#view view.DragDrop}}

            {{#if uploadStatus.error}}
                <div class="error">An error occurred during the upload process. Please try again later.</div>
            {{/if}}

            {{#each controller.validFiles}}

                <div {{bind-attr class="className:image"}}>
                    {{name}}
                    <a class="remove" {{action "deleteFile" this}}>Discard.</a>
                    {{view view.ImagePreview imageBinding="this"}}
                </div>

            {{/each}}

            {{view view.MultipleInput}}

        {{/view}}
    </div><!-- /#media-upload -->

</div><!-- /.row -->

media.js

App.MediaController = Ember.ArrayController.extend(DropletController, {
    dropletUrl: 'http://localhost:3000/images',

    uploadedSomeFiles: function uploadedSomeFiles() {
        var files = this.get('uploadedFiles');
        files.forEach(function(file) {
                // This gets fired every-time a file has uploaded successfully
                console.log(file + ' was uploaded!');
        });
    }.observes('files.length', 'files.@each.uploaded')

});

そうそう、それが役立つ場合はモデル (私は ember-model を使用しています):

App.Site = Ember.Model.extend({
  title: attr(String),
  about_text: attr(String),
  is_custom_domain: attr(Boolean),
  subdomain: attr(String),
  url: attr(String),
  copyright: attr(String),
  site_desc: attr(String),
  meta_keywords: attr(String),
  footer_code: attr(String),
  header_code: attr(String),
  hide_site: attr(Boolean),
  user: belongsTo('App.User', {key: 'user_id'}),
  page: hasMany('App.Page', {key: 'pages', embedded: true}),
  media: hasMany('App.Media', {key: 'images', embedded: true})
  });

App.Media = Ember.Model.extend({
 file_size: attr(Number),
 width: attr(Number),
 height: attr(Number),
 url: attr(String),
 identifier: attr(String),
 current_path: attr(String),
 content_type: attr(String),
 thumb: attr(String),
 medium: attr(String),
 small: attr(String),
 tall_banner: attr(String),
 short_banner: attr(String),
 site: belongsTo('App.Site', {key: 'site_id'})
});

jQuery だけを使用すると、新しい画像をページに追加するのは非常に簡単ですが、何らかの理由で Ember を使用すると非常に複雑になります。(わかりました、公平を期すために、他のことは Ember を使用するとはるかに簡単になります。)

アップデート:

あなたはそれを知らないでしょうか、私は何日も(はい、何日も)問題に苦労し、それをstackoverflowに投稿してから数時間、答えに少し近づきました。

emberdroplet は標準の XMLHttpRequest を使用しているため、request.onload を使用して、Rails API から返された request.responseText にアクセスできることがわかりました。

わかりましたので、ここに私のコードがあります:

request.onload = function() {
  var media = App.Media.find();
  request.responseText.forEach(function(file, media) {
    media.pushObject(file);
    console.log(file.id);
  });
}

しかし、私はエラーを返しています:

この JSON が返されます。

{"id":93,"file_size":438162.0,"width":null,"height":null,"url":"/uploads/image/image/93/blevins_header_2013_v6.jpg", etc.

これがビューに追加されます:

<a class="th" data-bindattr-276="276">
  <img data-bindattr-278="278">
</a>

つまり、Ember-model は未加工の JSON をどう処理すればよいかわからないので、最初に何かを行う必要があります。

何か案は?

4

2 に答える 2

0

わかりました、それで私はついに自分でそれを理解しました。最善の方法ではないかもしれませんが、ここに行きます。

主なハードルの 1 つは、mixin が私の Rails バックエンドに配列のような名前を提供していないという発見でした。彼の言葉では:

Node.js は画像の配列を推測するのに十分賢いですが、Ruby/PHP では配列のような名前を指定する必要があります。

開発者は親切にこれを追加しました。(このコミットを参照してください: https://github.com/Wildhoney/EmberDroplet/commit/c769268084a006704f68f6993bb999e796762e4e )

したがって、MediaControllerこの種の作業を行っている他の人のための完全なコードを次に示します。

App.MediaController = Ember.Controller.extend(DropletController, {
    dropletUrl: 'http://localhost:3000/images',

    useArray: true,

    actions:{ 
        uploadAllFiles: function() {
            var self = this;
            $.when(self._super()).then(function(data){
                var media = App.Media.find();

                // console.log(data);

                $.each(data, function(idx, obj) {
                    media.pushObject(obj);
                });
                // media.save();
                media.reload();
            });
        }
    }
});

uploadAllFilesすべてのファイルがアップロードされた後に呼び出され、Rails API からオブジェクト (つまり、新しく作成されたモデル) を返します。

media.reload();新しく追加されたオブジェクトに対して任意のアクション (つまり、deleteImage) が機能するように呼び出す必要があります。

于 2014-04-01T22:42:05.140 に答える
0

サーバー側で作成された後、新しいメディア モデルを取得する必要があります。方法はあなた次第です。

たとえば、this.store.find('media')毎回すべてのモデルをフェッチするように呼び出すことができます。

または、Media モデルを作成するためのサーバー側ルートMediaRoute.modelを返し、追加するように設定します。this.store.filter('media')次に、クライアントで、アップロードされたすべてのファイルに対して新しいモデルを手動で作成して保存する必要があります (ember-data は、フィルタリングされた配列にそれらを自動的に挿入します)。

または、すべての ajax 作業を自分で処理することもできます。非常に単純なjQueryの方法が必要な場合は、テンプレートを にバインドし{{#each file in files}}ます。これは、アップロードされたファイルを反復処理します(file.urlまたはsmthを使用してください。よくわかりません)。既にアップロードされたファイルをロードするには$.getJSON、メソッドを使用して、すべてのファイルをレスポンスからMediaController.filesプロパティに追加します (この方法はお勧めしませんが、簡単にすることは可能です)。

于 2014-03-21T22:25:55.017 に答える