mirror of
https://github.com/flarum/core.git
synced 2025-10-15 17:04:26 +02:00
Allow extensions to use route resolvers (#2275)
- mapRoutes: don't wrap components in resolvers if they are already resolvers - Extract defaultResolver into its own class - Allow either route resolver instances, or components with an optional resolverClass which should accept the component and route name in its constructor. - Introduce a resolver for DiscussionPage, so that routing from one post to another on the same discussion triggers a scroll instead of rerendering
This commit is contained in:
committed by
GitHub
parent
c1d91be2f4
commit
988b6c9023
@@ -67,6 +67,7 @@ import username from './helpers/username';
|
||||
import userOnline from './helpers/userOnline';
|
||||
import listItems from './helpers/listItems';
|
||||
import Fragment from './Fragment';
|
||||
import DefaultResolver from './resolvers/DefaultResolver';
|
||||
|
||||
export default {
|
||||
extend: extend,
|
||||
@@ -138,4 +139,5 @@ export default {
|
||||
'helpers/username': username,
|
||||
'helpers/userOnline': userOnline,
|
||||
'helpers/listItems': listItems,
|
||||
'resolvers/DefaultResolver': DefaultResolver,
|
||||
};
|
||||
|
34
js/src/common/resolvers/DefaultResolver.ts
Normal file
34
js/src/common/resolvers/DefaultResolver.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import Mithril from 'mithril';
|
||||
|
||||
/**
|
||||
* Generates a route resolver for a given component.
|
||||
* In addition to regular route resolver functionality:
|
||||
* - It provide the current route name as an attr
|
||||
* - It sets a key on the component so a rerender will be triggered on route change.
|
||||
*/
|
||||
export default class DefaultResolver {
|
||||
component: Mithril.Component;
|
||||
routeName: string;
|
||||
|
||||
constructor(component, routeName) {
|
||||
this.component = component;
|
||||
this.routeName = routeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* When a route change results in a changed key, a full page
|
||||
* rerender occurs. This method can be overriden in subclasses
|
||||
* to prevent rerenders on some route changes.
|
||||
*/
|
||||
makeKey() {
|
||||
return this.routeName + JSON.stringify(m.route.param());
|
||||
}
|
||||
|
||||
onmatch(args, requestedPath, route) {
|
||||
return this.component;
|
||||
}
|
||||
|
||||
render(vnode) {
|
||||
return [{ ...vnode, routeName: this.routeName, key: this.makeKey() }];
|
||||
}
|
||||
}
|
@@ -1,6 +1,9 @@
|
||||
import DefaultResolver from '../resolvers/DefaultResolver';
|
||||
|
||||
/**
|
||||
* The `mapRoutes` utility converts a map of named application routes into a
|
||||
* format that can be understood by Mithril.
|
||||
* format that can be understood by Mithril, and wraps them in route resolvers
|
||||
* to provide each route with the current route name.
|
||||
*
|
||||
* @see https://mithril.js.org/route.html#signature
|
||||
* @param {Object} routes
|
||||
@@ -13,12 +16,14 @@ export default function mapRoutes(routes, basePath = '') {
|
||||
for (const routeName in routes) {
|
||||
const route = routes[routeName];
|
||||
|
||||
map[basePath + route.path] = {
|
||||
render() {
|
||||
const key = routeName + JSON.stringify(m.route.param());
|
||||
return [m(route.component, { routeName, key })];
|
||||
},
|
||||
};
|
||||
if ('resolver' in route) {
|
||||
map[basePath + route.path] = route.resolver;
|
||||
} else if ('component' in route) {
|
||||
const resolverClass = 'resolverClass' in route ? route.resolverClass : DefaultResolver;
|
||||
map[basePath + route.path] = new resolverClass(route.component, routeName);
|
||||
} else {
|
||||
throw new Error(`Either a resolver or a component must be provided for the route [${routeName}]`);
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
|
Reference in New Issue
Block a user