【问题标题】:Updating an Emberjs view as objects are updated在对象更新时更新 Emberjs 视图
【发布时间】:2014-03-21 17:18:25
【问题描述】:

我正在使用这个不错的 Ember.js mixin:https://github.com/Wildhoney/EmberDroplet 来通过拖放上传图片,它运行良好。

唯一的问题是,我不知道如何在图片上传后将它们添加到视图中。该模型在我的 Rails API 中得到正确更新,但是,由于没有真正刷新整个页面,我不知道如何在 Ember 中更新模型。

这是我的代码的一些 sn-ps:

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,所以我应该先对其进行处理,对吧?

有什么想法吗?

【问题讨论】:

    标签: javascript ember.js ember-model


    【解决方案1】:

    您需要在服务器端创建新的媒体模型后获取它。路由你自己决定。

    例如,您可以每次调用this.store.find('media') 获取所有模型。

    或将MediaRoute.model 设置为返回this.store.filter('media') 并添加用于创建媒体模型的服务器端路由。然后在客户端,您需要为每个上传的文件手动创建一个新模型并保存它们(ember-data 自动将它们插入到过滤后的数组中)。

    或者您可以自己处理所有 ajax 工作。如果您想要一个简单的 jQuery 方式,请将模板绑定到 {{#each file in files}},它会遍历上传的文件(使用 file.url 或 smth,我不确定)。要加载已上传的文件,请使用 $.getJSON 方法并将响应中的每个文件添加到 MediaController.files 属性(我不推荐这种方式,但它可能很简单)。

    【讨论】:

    • 您好,感谢您的回复。我正在使用 ember-model,所以我不确定如何用它来实现它。我想出了一个方法,并将其发布为我的答案。谢谢。
    【解决方案2】:

    好的,所以我终于自己弄清楚了。也许不是最好的方法,但这里就是这样。

    主要障碍之一是发现 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)对新添加的对象起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-23
      • 1970-01-01
      • 2016-09-08
      • 1970-01-01
      • 2021-03-30
      • 1970-01-01
      相关资源
      最近更新 更多