Model 余烬(无余烬数据)数据缓存和延迟

Model 余烬(无余烬数据)数据缓存和延迟,model,ember.js,jquery-deferred,Model,Ember.js,Jquery Deferred,我一直在尝试在没有余烬数据的情况下使用余烬JS。我正在尝试连接到现有的JSON(但不是REST)API 我试图加载一个缩略图像网格,并通过单击它来显示所选图像的高分辨率预览 API分别调用获取文件集合和获取单个文件的详细信息。显然,我想避免仅仅为了获得预览高分辨率图像URL而拨打100次电话。因此,我的App.File.find和App.File.findAll使用不同的API调用 IMS.api.call是一个围绕jQuery.ajax的简单包装器,它返回一个承诺 问题:网格加载良好(/#/f

我一直在尝试在没有余烬数据的情况下使用余烬JS。我正在尝试连接到现有的JSON(但不是REST)API

我试图加载一个缩略图像网格,并通过单击它来显示所选图像的高分辨率预览

API分别调用获取文件集合和获取单个文件的详细信息。显然,我想避免仅仅为了获得预览高分辨率图像URL而拨打100次电话。因此,我的App.File.find和App.File.findAll使用不同的API调用

IMS.api.call
是一个围绕
jQuery.ajax
的简单包装器,它返回一个承诺

问题:网格加载良好(
/#/files/
),但是,如果单击单个图像,预览将使用缩略图而不是预览图像(
/#/files/1165931501
)。然而,如果我刷新浏览器,我会得到一个高分辨率的版本

添加一些日志记录,我发现在第一个版本中,
App.File.find
从未被调用。刷新时,它会被调用一次

我尝试过的事情:

我添加了一个computed属性,该属性进行单独调用以获取hi-res url:

bigUrl: function(){
    var id = this.get('content.id');
    preview = App.File.find(id);
    return preview.url;         
}.property('id')
但是jQuery调用返回的延迟在视图呈现时尚未加载,因此bigUrl未定义。所以我试着将其包装在一个承诺中,但余烬抱怨说计算属性不能返回一个承诺

我到处寻找如何鼓励ember调用
App.File.find
,但没有结果

有什么想法吗

window.App = Ember.Application.create();

App.Router.map(function() {
  this.resource('files',function(){
    this.resource('file',{path:':file_id'});
  });
});

App.IndexRoute = Ember.Route.extend({
    redirect: function(){
        this.transitionTo('files');
    }
});

App.FilesRoute = Ember.Route.extend({
  model: function() {
    return App.File.findAll();
  }
});

App.FileRoute = Ember.Route.extend({
    model: function(args) {
        return App.File.find(args.file_id);
    }
});

App.File = Ember.Object.extend({});
App.File.reopenClass({
    find: function(id){
        return IMS.api.call("Files.GetAssetDetails",{"assetId":id}).then(
            function(response) {
                file = response.outParams;
                return App.File.create({'id':file.id,'filename':file.filename,"url":file.panoramicUrl});
            }
        );
    },  

    findAll: function() {
        return IMS.api.call("Files.GetAssetsForParent",{"containerId":11659314773}).then(
            function(response) {
                var files = [];
                response.outParams.forEach(function (file) {
                    files.push(App.File.create({'id':file.id,'filename':file.filename,"url":file.thumbUrl}));
                });
                return files;
            }
        );
    },
});
[更新]

视图如下所示:

应用程序:

<script type="text/x-handlebars" data-template-name="application">
  <div class="row">
    <div class="twelve columns">
      <h1>/pics/</h1>
      <hr>
      {{outlet}}
    </div>
  </div>
</script>

/照片/

{{outlet}}
档案:

<script type="text/x-handlebars" data-template-name="files">
    <div class="row">

      <div class="six columns">
        {{outlet}}
      </div>

      <div class="six columns" id='chooser'>
        {{#each file in model}}
        <div style='float:left'>
          <div>
            {{#linkTo file file}}
              <img {{bindAttr src="file.url"}} style='width:100px;height:100px;'>
            {{/linkTo}}
          </div>
        </div>
        {{/each}}
      </div>
    </div>
</script>

{{outlet}}
{{{#模型中的每个文件}
{{{#链接到文件}
{{/linkTo}
{{/每个}}
文件


{{log id}}{{log url}
{{id}

要在每次路线更改时强制重新加载模型,需要从
设置控制器进行调用

每次路线更改时都会调用
setupController
。我选择将模型作为函数调用,而不是重复
App.File.find
调用

App.FileRoute = Ember.Route.extend({
    setupController: function(controller,model){
        console.log("setupController",controller,model);
        controller.set('model',this.model({file_id:model.id}));
    },
    model: function(params) {
        return App.File.find(params.file_id);
    }
});
不幸的是,如果你要回报一个承诺,这是行不通的。要让它工作,你必须返回一个对象,并承诺稍后填写它

find: function(id){
    file = App.File.create({});
    IMS.api.call("Files.GetAssetDetails",{"assetId":id,"fields":{"metadata":true}}).then(function(response) {
        file.setProperties({'id':response.outParams.id,'filename':response.outParams.filename,"url":response.outParams.panoramicUrl,"metadata":response.outParams.metadata});
        }
    );
    return file;
},  
这确实会偶尔出现一个错误:

TypeError:“未定义”不是对象(正在计算“response.outParams.id”)

这是由于
setupController
没有从模型中获取有效的id,然后处理undefined以查找它的第一次调用

一定有更好的方法从路线中获取id。。。有人吗

[更新]

下面是我如何停止错误的:

setupController: function(controller,model){
    if(model.isLoaded == false){
        controller.set('model',model);
    } else {
        controller.set('model',this.model({file_id:model.id}));
    }
},
我在find函数中添加了一个“.isLoaded”标志:

find: function(id){
    file = App.File.create({isLoaded: false});
    IMS.api.call("Files.GetAssetDetails",{"assetId":id,"fields":{"metadata":true}}).then(function(response) {
        file.setProperties({'id':response.outParams.id,'filename':response.outParams.filename,"url":response.outParams.panoramicUrl,"metadata":response.outParams.metadata});
        file.set('isLoaded', true);
    });
    return file;
},  

你能发布文件索引模板吗?我怀疑您可能正在将一个文件对象作为上下文传递,其中包含指向该对象的链接。您的意思是:
{{{linktofile}}
?是的,我的意思是。但是仔细想想,可能已经为索引加载了一个具有正确id的文件,您只需要以某种方式刷新/更新它。我已经尝试过了——添加第二个ajax调用,它将遍历所有文件并将url设置为更大的值。尽管数据正在更新,但视图从未刷新。您是否尝试在
文件路径的
设置控制器
钩子中执行此操作?是否考虑使用
afterModel
钩子?它与承诺配合得很好。
find: function(id){
    file = App.File.create({isLoaded: false});
    IMS.api.call("Files.GetAssetDetails",{"assetId":id,"fields":{"metadata":true}}).then(function(response) {
        file.setProperties({'id':response.outParams.id,'filename':response.outParams.filename,"url":response.outParams.panoramicUrl,"metadata":response.outParams.metadata});
        file.set('isLoaded', true);
    });
    return file;
},