4

我的路线中有一个setupControllermodel钩子。model.find(param) 持有对 rails 后端的 ajax 调用。

发生的事情是我的模型钩子触发并调用后端。但是在后端回答并且成功回调实际上与模型一起返回之前,setupController钩子会触发一个仍未定义的模型。

最终结果是,当模型本身通过绑定系统进行更新时,需要在 setupController 中进行的附加设置不起作用。我觉得我以某种方式设置了模型的内容错误,但无法弄清楚。

顺便说一句,如果我使用后退和前进按钮进行导航,就会发生这种情况。如果我通过#linkTo指定对象的路线进入,一切都会按预期工作。

如果有人有一个很棒的想法,我的代码如下。

App.ProjectsEditRoute = Ember.Route.extend({
  model: function(params) {
    return App.Project.find(params.project_id);
  },

  setupController: function(controller, model) {
    this.controllerFor('activedataset.index').set('content', App.ActiveDataSet.findAll(model.id));
  }
});

App.Project = Ember.Object.extend({
  id: '',
  name: ''
});

App.Project.reopenClass({
  findAll: function() {
    var result = Ember.ArrayProxy.create({content: []});
    var self = this;
    $.ajax({
      url: '/projects.json',
      type: 'GET',
      data: {'user_id': App.currentUser.id},
      success: function(data, textStatus, xhr) {
        result.set('content', data.projects);
      },
      error: function(xhr, textStatus, errorThrown) {
        alert('error');
      }
    });

    return result;
  },

  find: function(project_id) {
    var result = Ember.Object.create({content: null});
    var self = this;
    $.ajax({
      url: '/projects/' + project_id + '.json',
      type: 'GET',
      success: function(data, textStatus, xhr) {
        result.setProperties(data.project);
      },
      error: function(xhr, textStatus, errorThrown) {
        alert('not found');
      }
    });

    return result;
  }
});

在 Mike 提供的解决方案后编辑:

App.ProjectsEditRoute = Ember.Route.extend({
  model: function(params) {
    var record = App.Project.find(params.project_id);
    var promise = Ember.Deferred.create();
    record.addObserver('isLoaded', function() {
      promise.resolve(record);
    });

    return promise;
  },

  setupController: function(controller, model) {
    this.controllerFor('activedataset.index').set('content', App.ActiveDataSet.findAll(model.id));
  }
});

App.Project.reopenClass({
  find: function(project_id) {
    var result = Ember.Object.create({content: null, isLoaded: false});
    var self = this;
    $.ajax({
      url: '/projects/' + project_id + '.json',
      type: 'GET',
      success: function(data, textStatus, xhr) {
        result.setProperties(data.project);
        result.set('isLoaded', true);
      },
      error: function(xhr, textStatus, errorThrown) {
        alert('not found');
      }
    });

    return result;
  }
});
4

2 回答 2

4

我觉得我以某种方式设置了模型的内容错误,但无法弄清楚。

你的所作所为本身并没有错。如果您需要 ember 路由器等待模型 ajax 完成,然后再继续 setupController 挂钩,您的模型的 find() 应该返回一个承诺。如果路由的模型钩子返回一个承诺,ember 路由器将等待承诺解决后再继续。

By default ember-data's model objects return a promise when you call find({}). It should be easy to do the same for your model, see this Ember initializing route model with query for an example of the deferred patter.

This only happens by the way if I use the back and forward button to navigate. If I go in the route through an #linkTo with the object specified everything works as expected.

Makes sense. When you use a #linkTo the data is already loaded.

于 2013-03-19T19:45:15.693 回答
0

You probably should use this.store.find('project') instead of rolling your own App.Project.find().

DS uses promises, and therefore calling code will wait for fetched object(s).

What is somewhat undercommunicated in regards to rails and ember working together, is that you probably should use ActiveModel::Serializers in your rails controllers and the ams adapter in DS.Store for best and expected results.

App.Store = DS.Store.extend({
    // Override the default adapter with the `DS.ActiveModelAdapter` which
    // is built to work nicely with the ActiveModel::Serializers gem.
    adapter: '_ams'
});

My experience is that you are in for a world of pain if you start sidestepping Ember and/or DS. The hard part of using Ember is that you, arguably, have to understand every facet of it to be effective.

于 2014-01-23T12:57:55.537 回答