Javascript 延迟加载模型中的关联
在我的Ember.js应用程序中,我有一个如下所示的模型:Javascript 延迟加载模型中的关联,javascript,ruby-on-rails,ember.js,Javascript,Ruby On Rails,Ember.js,在我的Ember.js应用程序中,我有一个如下所示的模型: MyApp.Game = DS.Model.extend({ season_type: DS.attr('string'), gamedate: DS.attr('date'), home_team_name: DS.attr('string'), visiting_team_name: DS.attr('string'), gametime:
MyApp.Game = DS.Model.extend({
season_type: DS.attr('string'),
gamedate: DS.attr('date'),
home_team_name: DS.attr('string'),
visiting_team_name: DS.attr('string'),
gametime: DS.attr('string'),
home_team: DS.belongsTo('team'),
visiting_team: DS.belongsTo('team'),
home_team_pitcher: DS.belongsTo('player'),
visiting_team_pitcher: DS.belongsTo('player'),
home_players: DS.hasMany('player'),
visitor_players: DS.hasMany('player')
});
这在控制器“A”中工作得很好。在另一个控制器中,我们称之为控制器“B”,理想情况下,我还有两个属性可用,如下所示:
MyApp.Game = DS.Model.extend({
season_type: DS.attr('string'),
gamedate: DS.attr('date'),
home_team_name: DS.attr('string'),
visiting_team_name: DS.attr('string'),
gametime: DS.attr('string'),
home_team: DS.belongsTo('team'),
visiting_team: DS.belongsTo('team'),
home_team_pitcher: DS.belongsTo('player'),
visiting_team_pitcher: DS.belongsTo('player'),
home_players: DS.hasMany('player'),
visitor_players: DS.hasMany('player'),
home_all_players: DS.hasMany('player'),
visitor_all_players: DS.hasMany('player')
});
在本例中,我添加了home\u all\u players
和visitor\u all\u players
。在这两个属性中有大量的数据需要跨线传输,我希望避免将其用于面向客户的控制器a
。另一方面,controllerB
是一个管理界面,管理员需要访问home\u all\u players
和visitor\u all\u players
,以便更新MLB团队的阵容
最干净的处理方法是什么?我猜在服务器端,在我使用Ruby on Rails的地方,我只会让序列化程序包括
home\u all\u players
和visitor\u all\u players
,这取决于调用的路由。但是Ember.js端的建模保持不变,所以我不确定解决这个问题的最佳方法是什么 我认为,这取决于你的整个应用程序流程和交互,如果你希望你的用户体验任何过渡延迟或特定用户体验,那么你需要访问一组特定的数据
一般来说,我的后端负责为其客户机提供最方便的API,因此他们可以提供最好的UX,为此,您可以使用嵌入式数据、侧载资源、新的资源定义等
我在三个不同的方面做了类似的事情:
1) 发送查询参数,以便服务器知道如何序列化资源
store.find('game', {id: 1, extend:'admin'});
store.find('game', {extend:'admin'});
MyApp.ExtendedGame = DS.Model.extend({
game: DS.belongsTo('game'),
home_all_players: DS.hasMany('player'),
visitor_all_players: DS.hasMany('player')
});
2) 根据您当前的用户身份验证,您的服务器可以知道资源应该如何序列化
//the server response would be different based on the auth header
store.find('game', 1);
store.find('game');
3) 包括扩展资源的新资源
store.find('game', {id: 1, extend:'admin'});
store.find('game', {extend:'admin'});
MyApp.ExtendedGame = DS.Model.extend({
game: DS.belongsTo('game'),
home_all_players: DS.hasMany('player'),
visitor_all_players: DS.hasMany('player')
});
在我看来,你需要扩展你的模型
App.Game = DS.Model.extend({
...
});
App.AdminGame = App.Game.extend({
home_players: DS.hasMany('player'),
visitor_players: DS.hasMany('player')
});
在本例中,您将有两个控制器和相关路由,它们是AdminGameController、GameController、GameRoute和AdminGameRoute
您应该从相关路由中的服务器获取适当的模型。Rails应根据控制器返回正确的模型。我使用查询参数,在Rails端,
ActiveModel::Serializer
确定是否包含字段、字段数量、排序顺序等。不过,我不确定是否会在客户端上使用不同的控制器
我即将开始一个类似的功能,更一般地说,对大量数据进行分页。我现在的想法是扩展
DS.ManyArray
并在meta
中添加一些数据,其中包括加载的计数
,总计数
,偏移量
,等等,所有这些都可以由API返回。默认情况下,可以加载20条记录,然后调用函数添加更多记录,或者将窗口切换到另一个范围,以控制内存。或者,通过一个查询参数,将它们全部加载。您可以创建一个具有默认属性的基类和一个具有home\u all\u players
和visted\u all\u players
属性的继承类,而不是在单个模型上进行中继
这将是一种更好的OO方法(IMHO)
对于控制器\u A
MyApp.Game = DS.Model.extend({
season_type: DS.attr('string'),
gamedate: DS.attr('date'),
home_team_name: DS.attr('string'),
visiting_team_name: DS.attr('string'),
gametime: DS.attr('string'),
home_team: DS.belongsTo('team'),
visiting_team: DS.belongsTo('team'),
home_team_pitcher: DS.belongsTo('player'),
visiting_team_pitcher: DS.belongsTo('player'),
home_players: DS.hasMany('player'),
visitor_players: DS.hasMany('player')
});
对于控制器\u B
MyApp.AdminGame = MyApp.Game.extend({
home_all_players: DS.hasMany('player'),
visitor_all_players: DS.hasMany('player')
});
这同样适用于Rails模型。像这样更改您当前的模型
class Game < ActiveModel::Serializer
## Your code ..
def home_all_players
nil
end
def visitor_all_players
nil
end
## Your code ..
end
类游戏
并使用这些属性为管理员(扩展游戏)创建一个新模型
class AdminGame < Game
def home_all_players
self.home_all_players
end
def visitor_all_players
self.visitor_all_players
end
end
class-AdminGame
如果不想在现有模型中返回nil,请在json呈现期间排除这些属性。参考此