FEATURE: cache search results for 5 route transitions

DEV: transientCache that can be used to hold data for N route transitions
FEATURE: remember scroll position when hitting back from full page search
This commit is contained in:
Sam 2015-09-09 11:52:11 +10:00
parent 1c90f77d09
commit 5eb1fb3bfd
5 changed files with 56 additions and 16 deletions

View File

@ -1,4 +1,4 @@
import { translateResults, searchContextDescription } from "discourse/lib/search";
import { translateResults, searchContextDescription, getSearchKey } from "discourse/lib/search";
import showModal from 'discourse/lib/show-modal';
import { default as computed, observes } from 'ember-addons/ember-computed-decorators';
import Category from 'discourse/models/category';
@ -64,6 +64,8 @@ export default Ember.Controller.extend({
canBulkSelect: Em.computed.alias('currentUser.staff'),
search(){
const router = Discourse.__container__.lookup('router:main');
this.set("q", this.get("searchTerm"));
this.set("model", null);
@ -77,8 +79,12 @@ export default Ember.Controller.extend({
};
}
const searchKey = getSearchKey(args);
Discourse.ajax("/search", { data: args }).then(results => {
this.set("model", translateResults(results) || {});
const model = translateResults(results) || {};
router.transientCache('lastSearch', { searchKey, model }, 5);
this.set("model", model);
});
},

View File

@ -6,6 +6,9 @@ export default {
initialize(container) {
const cache = {};
var transitionCount = 0;
// Tell our AJAX system to track a page transition
const router = container.lookup('router:main');
router.on('willTransition', function() {
@ -14,8 +17,23 @@ export default {
router.on('didTransition', function() {
Em.run.scheduleOnce('afterRender', Ember.Route, cleanDOM);
transitionCount++;
_.each(cache, (v,k) => {
if (v && v.target && v.target < transitionCount) {
delete cache[k];
}
});
});
router.transientCache = function(key, data, count) {
if (data === undefined) {
return cache[key];
} else {
return cache[key] = {data, target: transitionCount + count};
}
};
const pageTracker = PageTracker.current();
pageTracker.start();

View File

@ -101,4 +101,9 @@ const searchContextDescription = function(type, name){
}
};
export { searchForTerm, searchContextDescription };
const getSearchKey = function(args){
return args.q + "|" + ((args.searchContext && args.searchContext.type) || "") + "|" +
((args.searchContext && args.searchContext.id) || "")
};
export { searchForTerm, searchContextDescription, getSearchKey };

View File

@ -1,24 +1,37 @@
import { translateResults } from "discourse/lib/search";
import { translateResults, getSearchKey } from "discourse/lib/search";
export default Discourse.Route.extend({
queryParams: { q: {}, "context-id": {}, context: {} },
queryParams: { q: {}, context_id: {}, context: {} },
model(params) {
const router = Discourse.__container__.lookup('router:main');
var cached = router.transientCache('lastSearch');
var args = { q: params.q };
if (params.context_id && !args.skip_context) {
args.search_context = {
type: params.context,
id: params.context_id
}
}
const searchKey = getSearchKey(args);
if (cached && cached.data.searchKey === searchKey) {
// extend expiry
router.transientCache('lastSearch', { searchKey, model: cached.data.model }, 5);
return cached.data.model;
}
return PreloadStore.getAndRemove("search", function() {
if (params.q && params.q.length > 2) {
var args = { q: params.q };
if (params.context_id && !args.skip_context) {
args.search_context = {
type: params.context,
id: params.context_id
}
}
return Discourse.ajax("/search", { data: args });
} else {
return null;
}
}).then(results => {
return (results && translateResults(results)) || {};
const model = (results && translateResults(results)) || {};
router.transientCache('lastSearch', { searchKey, model }, 5);
return model;
});
},

View File

@ -1,3 +1 @@
import ScrollTop from "discourse/mixins/scroll-top";
export default Ember.View.extend(ScrollTop, {});
export default Ember.View.extend({});