【问题标题】:Ember.js - Asyncronous call in model find() methodEmber.js - 模型 find() 方法中的异步调用
【发布时间】:2012-08-21 22:40:24
【问题描述】:

我在我的属性模型上实现了find()findAll() 方法。这两种方法都对 API 进行异步调用。 findAll() 在连接我家路线的插座时被调用,并且工作正常。 find() 由 Ember.js 在连接我的属性路由的插座时调用。请注意,find() 在通过操作导航到属性路由时不会被调用,但在您通过 URL 直接进入路由时会被调用。

这是我的路由器:

App.Router = Ember.Router.extend({
    root: Ember.Route.extend({
        showProperty: Ember.Route.transitionTo('property'),
        home: Ember.Route.extend({
            route: '/',
            connectOutlets: function(router) {
                router.get('applicationController').connectOutlet('home', App.Property.findAll());
            }        
        }),
        property: Ember.Route.extend({
            route: '/property/:property_id',
            connectOutlets: function(router, property) {
                router.get('applicationController').connectOutlet('property', property);
            }
        }),
    })
});

这是我的 findAll()find() 方法:

App.Property.reopenClass({
    find: function(id) {
        var property = {};
        $.getJSON('/api/v1/property/' + id, function(data) {
            property = App.Property.create(data.property);
        });
        return property;
    },
    findAll: function() {
        var properties = [];
        $.getJSON('/api/v1/properties', function(data) {
            data.properties.forEach(function(item) {
                properties.pushObject(App.Property.create(item));
            });
        });
        return properties;
    }
});

当我转到索引以外的路线时,例如http://app.tld/#/property/1,路线将被重写为http://app.tld/#/property/undefined。没有任何内容被传递给 Property 控制器的 content 属性。如何在find() 方法中进行异步调用?除非我弄错了,否则异步调用在 findAll() 方法中可以正常工作,这是我困惑的根源。

这个问题类似于Deserialize with an async callback,但我使用的是find() 方法,而不是覆盖deserialize() 方法。

提前致谢。

【问题讨论】:

    标签: javascript ember.js


    【解决方案1】:

    我发现设置id 属性可以显式解决这个问题。在你的情况下,这看起来像这样。

    find: function(id) {
      var user = App.User.create();
    
      $.getJSON('/api/v1/property/' + id, function(data) {
        user.setProperties(data.user)
      });
    
      user.set("id",id); // <-- THIS
    
      return user;
    }
    

    一旦您的user 获得其属性,视图就会正常更新。 Ember 在更新 URL 之前只需要 id 部分。

    希望这会有所帮助:-)

    【讨论】:

      【解决方案2】:

      这就是您想要做的事情。我将模型更改为 User 以使事情更清晰。

      find() 的情况下,您返回一个空白模型实例,该实例在 AJAX 请求返回时填充其属性。 Ember 数据绑定的好处是您可以立即在视图中显示此模型,并且当 AJAX 请求返回并更新模型实例时,视图将更新。

      findAll() 的情况下,您返回一个空白数组,当 AJAX 请求返回时填充该数组。与find() 一样,您可以在视图中显示此模型列表(最初为空白),当 AJAX 请求返回并填充数组时,视图将更新。

      App.User.reopenClass({
      
        find: function(id) {
          var user = App.User.create();
      
          $.getJSON('/api/v1/property/' + id, function(data) {
            user.setProperties(data.user)
          });
      
          return user;
        },
      
        findAll: function() {
          var userList = [];
      
          $.getJSON('/api/v1/properties', function(data) {
            var users = data.users.map(function(userData) {
              return App.User.create(userData);
            });
            userList.pushObjects(users);
          });
      
          return userList;
        }
      
      });
      

      【讨论】:

      • 我不认为,它解决了问题。我正在扩展 RESTAdapter,并将 find 替换为 code var root = this.rootForType(type); this.ajax(this.buildURL(root, id), "GET", { success: function(json) { store.load(type, json); } }); 刷新时,我的 URL 更改为 'tool/null/settings' ,其中 null 应该是字符串 ID。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-05
      • 2015-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多