我们需要保持我们的Firebase数据与其他同步databases的full-text search(在ElasticSearch)和其他种类的查询Firebase并不轻松支持.
这需要尽可能接近实时,我们不能只是导出夜间转储Firebase JSON或类似的东西,除了这将变得相当大.
我最初的想法是运行一个Node.js客户端,它会监听child_changed,child_added,child_removed等...所有的主清单的事件,但是这可能会有点unweildy,这将是同步的可靠方法,如果一段时间后,客户端重新连接时间?
我的下一个想法是维护一个"项目已更改"事件的列表,并在每次创建/更新项目时写入,类似于Firebase工作队列示例.队列可以包含已更改的数据的完整路径,工作人员只需消耗该数据并相应地更新本地数据库.
这里的问题是每一段代码都使得更新必须记住写入此队列,否则两个系统将失去同步.一些代理代码不应该太难写.
有没有其他人做过类似的任何成功?
假设我有以下ember-data模型:
App.Person = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
starred: DS.attr('boolean')
});
Run Code Online (Sandbox Code Playgroud)
这与使用以下非常标准的CRUD API的Rails应用程序通信:
GET /people - get a list of people
POST /people - create a new person
GET /people/id - get a specific person
PUT /people/id - update a specific person
DELETE /people/id - delete a specific person
Run Code Online (Sandbox Code Playgroud)
这些都使用标准存储/适配器映射到Ember-Data.
但是,让我们说,为了让一个人"明星化"或"解除明星化",API不允许我们通过标准更新操作来执行此操作.此操作有一个特定的API端点:
POST /people/id/star - mark a person as "starred"
POST /people/id/unstar - mark a person as "unstarred"
Run Code Online (Sandbox Code Playgroud)
如何在Ember Data中使用此API?
看起来我需要以某种方式扩展DS.Store和DS.RESTAdapter,但我不确定让他们了解这些不同操作的最佳方法.对于应用程序的通用适配器必须知道主演人员,也感觉有点不对劲.
请注意,我无法控制API,因此我无法POST /people/id了解"主演",因此它适合标准更新.
我有一个DS.Store使用DS.RESTAdapter和ChatMessage定义的对象:
App.ChatMessage = DS.Model.extend({
contents: DS.attr('string'),
roomId: DS.attr('string')
});
Run Code Online (Sandbox Code Playgroud)
请注意,房间中存在聊天消息(为简单起见未显示),因此在我的聊天消息控制器(扩展Ember.ArrayController)中,我只想为用户当前所在的房间加载消息:
loadMessages: function(){
var room_id = App.getPath("current_room.id");
this.set("content", App.store.find(App.ChatMessage, {room_id: room_id});
}
Run Code Online (Sandbox Code Playgroud)
这将设置content为a DS.AdapterPopulatedModelArray并且我的视图愉快地显示{{#each}}块中所有返回的聊天消息.
现在谈到添加新消息,我在同一个控制器中有以下内容:
postMessage: function(contents) {
var room_id = App.getPath("current_room.id");
App.store.createRecord(App.ChatMessage, {
contents: contents,
room_id: room_id
});
App.store.commit();
}
Run Code Online (Sandbox Code Playgroud)
这会启动ajax请求以在服务器上保存消息,到目前为止一切都很好,但它不会更新视图.这非常有意义,因为它是一个过滤结果,如果我删除了room_id过滤器,App.store.find那么它会按预期更新.
尝试this.pushObject(message)使用返回的消息记录App.store.createRecord会引发错误.
如何手动将项目添加到结果中?似乎没有成为一个办法,据我可以告诉既DS.AdapterPopulatedModelArray和DS.FilteredModelArray是不可变的.
假设我有一个显示基于属性的视图的模板:
{{#if App.contentsAreVisible}}
{{view ToggleContents}}
{{/if}}
Run Code Online (Sandbox Code Playgroud)
通过设置,可以通过UI的任意数量的其他部分切换此区域 App.set("contentsAreVisible", [true/false]);
一切正常.
但是,我现在想要在切换视图时进行动画处理.连接didInsertElement到动画显示区域的工作,但我不能这样做willDestroyElement因为在动画有机会运行之前,该函数返回后立即删除元素.
App.ToggleContents = Ember.View.extend({
// this works fine
didInsertElement: function(){
this.$().hide().show("slow");
},
// this doesn't work
willDestroyElement: function(){
this.$().hide("slow", function(){
// animation is complete, notify that the element can be removed
});
}
});
Run Code Online (Sandbox Code Playgroud)
有没有办法告诉视图推迟从DOM中删除元素,直到动画完成?
这是一个互动示例的小提琴:http://jsfiddle.net/rlivsey/RxxPU/
目前我正在使用JavaScript的本机sort()方法在Ember中进行排序,但实际上我知道我应该使用Ember自己的排序,但不幸的是我完全不知道如何使用它.
我不想浪费人们的时间为我解释(除非你是一个受虐狂),但如果有人知道如何在EmberJS中对一组模型进行排序的精彩文章,那么我们将不胜感激!
目前我有类似下面的内容,我只是在实现使用本机排序再次进行排序,但我在那里停下来因为我想学习正确的方法.
SortOption: Ember.View.extend(
{
template: Ember.Handlebars.compile('<li><a href="javascript:void(0);">{{ option }}</a></li>'),
option: null,
click: function()
{
var rootView = this.nearestWithProperty('people');
var sortBy = this.get('option');
var sorted = rootView.get('people').orderBy('formalName');
rootView.set('people', sorted)
}
})
Run Code Online (Sandbox Code Playgroud)