在backbone.js 中缓存集合?
确保我的集合保持缓存并仅获取一次的最佳方法是什么?
我应该实现某种缓存层吗?我应该将 Collection
变量共享到需要的地方吗?我可以信任 jQuery 的 AJAX 设置吗? ($.ajaxSetup ({ cache: true });
)
现在看起来的基本集合:
theCollection = Backbone.Collection.extend({
model: theModel,
url: "source.json"
});
if (typeof myCollection === 'undefined') {
var myCollection = new theCollection; // Only allow it to be created once
}
What would be the best way to ensure that my collection stays cached and thereby only gets fetched once?
Should I implement some sort of cache layer? Should I share the Collection
variable to wherever it is needed? Can I trust jQuerys AJAX setting? ($.ajaxSetup ({ cache: true });
)
The basic collection as it looks right now:
theCollection = Backbone.Collection.extend({
model: theModel,
url: "source.json"
});
if (typeof myCollection === 'undefined') {
var myCollection = new theCollection; // Only allow it to be created once
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我会在您的情况下实现一种集合管理器:
这里管理器负责实例化集合并获取它们。当您调用时:
您将获得示例集合的实例,其中数据已被获取。每当您再次需要此集合时,您可以再次调用该方法。然后您将获得完全相同的实例,无需再次获取它。
这只是一个非常简单的管理器示例,您可以实现和增强许多附加功能。
我强烈建议不要在较低级别上处理这个问题(例如 $.ajax 的传输层)。如果这样做,您将阻止多次获取您的集合,但最终您的应用程序中会出现具有相同 id 的不同模型实例。每个集合实例都会创建它自己的模型。
在我目前正在开发的 CouchApp 中,我还发现有必要防止不同集合中的重复模型实例(不同的数据库视图可以返回相同的模型数据)。这个问题已通过在管理器中建立一个单独的集合来解决,该集合跟踪已加载到应用程序中的所有模型。
最后但并非最不重要的一点是,您可能会考虑在集合或管理器中实现刷新方法,以处理从服务器更新集合的情况。如果您使用 fetch 方法执行此操作,您的整个集合将被重置,因此所有模型都会被销毁,然后重新创建。如果您在应用程序的其他地方引用了该集合中的模型(就像您通常所做的那样),那么这很糟糕。这些实例已过时并在您的应用程序中重复。刷新方法检查当前集合中是否已存在具有传入 id 的实例。如果是,则更新它们,否则添加它们。
I would implement a sort of collection manager in your case:
Here the manager is responsible for instantiating collections and fetching them. When you call:
you get an instance of example collection with data being already fetched. Whenever you need this collection again you can call the method again. You will then get the exact same instance with no need to fetch it again.
This is just a very simple manager example, and there are a lot of additional features you can implement and enhance.
I would strongly advise not to handle this issue on a lower level (eg. the transport layer of $.ajax). If you do that, you would prevent your collection from getting fetched multiple times, but you end up having different model instances with the same id floating around your application. Every collection instance would create it's own models.
In a CouchApp I am currently working on, I also found it necessary to prevent duplicate model instances in different collections (different db views can return the same model data). This has been solved by having a separate collection in the manager, which keeps track of all models already loaded into the application.
Last but not least you might consider implementing a refresh method in your collections or the manager that will handle updating the collection from the server. If you do this with the fetch method your whole collection is reseted so all models are destroyed and then recreated. This is bad if you have models from this collection referenced somewhere else in the app (as you typically do). Those instances are outdated and duplicated in your app then. The refresh method checks wether instances with the incoming id are already present in the curent collection. If so they are updated, otherwise they are added.
如果缓存实际上是指单例,以便您可以在模块化 JS 应用程序中的多个位置引用相同的域列表,我们使用 RequireJS 为此。您可以将集合分离为应用程序中的一个模块,然后无论您在哪里使用它都需要它。用伪代码表示:
您的回调函数将始终获得与定义 myCollection 模块时返回的相同实例。从所有视图绑定到该实例,每当刷新时,这些视图都会获得事件触发器并可以自行更新。
If by caching you actually mean a singleton, so that you can reference the same domain list from multiple places in a modular JS application, we use RequireJS for this. You can separate your collection to be a module in the application, which you then require wherever you are using it. In pseudocode:
Your callback function will always get the same instance you returned when you define your myCollection module. Bind to that instance from all your views, and whenever it is refreshed, those views will get an event trigger and can update themselves.
您可以尝试将您的收藏保存在 localStorage 中。这是链接( http://documentcloud.github.com/backbone/#examples-todos< /a>)。
该应用程序使用 LocalStorage 适配器透明地将所有待办事项保存在浏览器中,而不是将它们发送到服务器。
我希望它有帮助:)
You can try to save your collection in localStorage. Here is the link ( http://documentcloud.github.com/backbone/#examples-todos ).
The app uses a LocalStorage adapter to transparently save all of your todos within your browser, instead of sending them to a server.
I hope it helps :)
一个简单的解决方案是为您的集合创建一个全局变量,以便所有 javascript 代码都将使用相同的变量。
只需在页面加载时获取集合
由于 var 没有用于声明 myCollection,那么它就成为全局变量。
当然,这是一个简单的实现。有更强大的实现,但根据您的需求,它们可能有点矫枉过正。
A simple solution would be to make a global variable for your collection so that all your javascript code will use the same variable.
Just fetch the collection when the page loads
Since var is not used to declared myCollection, then it becomes a global variable.
Of course this is a simple implementation. There are more robust implementations, but depending on your needs, they might be overkill.
我最终做了类似于 ProTom 的解决方案。我决定只使用一个函数来设置集合,而不是根据名称动态初始化集合。通过我的应用程序,我需要根据集合的来源以不同的方式初始化集合。事实证明这是满足我需求的最佳方式。这是 CoffeeScript:
缓存:
用法:
I ended up doing something similar to ProTom's solution. Instead of dynamically initializing a collection based on the name, I decided to just use a function to setup the collection. Through my application, I needed to initialize collections differently depending on where it was coming from. This proved to be the best way for my needs. Here's the CoffeeScript:
Cache:
Usage:
您可以尝试
https://github.com/mrappleton/backbone-fetch-cache
它还具有过期支持,可以轻松设置缓存的最大时间。
You can try out
https://github.com/mrappleton/backbone-fetch-cache
It also has expires support that is easy to set maximum time of the cache.