A good way to define default rendering templates in FlowRouter

廉价感情. 提交于 2020-01-03 18:58:57

问题


When migrating to a new Meteor project which was replacing Iron-Router with Flow-Router, I really missed the functionality of Iron-Router to define default behaviours and settings that were usable globally.

I understand Flow-Router uses the "group" construct to be able to define default hook events which can be applied to any route attached to that group, but there seemed to be nothing available for defining default templates.

What is the best way to implement this type of default global or group template feature?


回答1:


I decided to use a simple abstraction which would allow simulation of this feature of Iron-Router. I am trying evaluate whether or not this is a sound and extensible pattern, before I look into more direct integration of such a feature within FlowRouter itself, and also to share this idea with others who are looking for a similar solution.

I simply created an object which is used as a parameter object template which is modified as needed and then passed when calling BlazeLayout.render.

This is what routes.js might look like:

var appRouteGroup = FlowRouter.group({
  name: "appRouteGroup",
  triggersEnter: [sometrigger]
});

var appRouteTemplates = {
  menuMain: "appNav",
  footerMain: "appFooter"
};

appRouteGroup.route("home", {
  name: "home",
  action: function () {
    // We get the default templates
    var templates = appRouteTemplates;

    // Now we can add the route specific template
    templates.content = "homePage";

    // Then render with templates passed through the object param
    BlazeLayout.render("mainLayout", templates);
  }
});

This will then allow you to render the default group templates without having to redefine them for every route. And with template markup as follows:

<template name="mainLayout">
  {{>Template.dynamic template=menuMain}}

  {{>Template.dynamic template=content}}

  {{>Template.dynamic template=footerMain}}
</template>

I'm looking for a way to maybe make a more direct integration within FlowRouter, but this seems perfectly functional. Any thoughts for improvements?




回答2:


I wanted so submit another solution that I have found, which adds a more comprehensive method of creating route "default" parameters for Flow-router.

It uses an atmosphere package called Flow-router-tree:

This package allows one to define routes as a series of "nodes" which can be linked to "parents" and which will then inherit the default parameters set within the definition of that parent. It would be interesting to see others comments on this package.




回答3:


UPDATED BELOW:

I have worked out what I think is a fairly effective and efficient way to do this.

In reviewing the functionality of Flow-Router, I noticed that the router object includes a field which contains all group parameters, in FlowRouter.current().route.group.options

This object contains any key-value pair defined in the group, regardless of whether they are used by the Flow-Router API or not.

I then decided to use this as a simple way of passing some template defaults from the group to the router.

First is the group definition:

var mainRoutes = FlowRouter.group({
  name: "mainRoutes",
  defaultTemplates: {
    menu: "mainMenu",
    breadcrumb: "mainCrumb",
    sidebarLeft: "sidebarLeft",
    sidebarRight: "sidebarRight",
    footer: "mainFooter"
  }
});

Then in defining the route we can access these from this.group.options.defaultTemplates

mainAppRoutes.route('/', {
  name: "home",
  action: function() {
    // Get the defaultTemplates object
    var templates = this.group.options.defaultTemplates;
    // Add route specific templates
    templates.content = "homeScreen";
    // Pass all the templates to the renderer
    BlazeLayout.render("appLayoutMain", templates);
  }
});

I like this pattern because it uses existing features of Flow-Router, and one extra line of code in the route, while allowing for defining of group wide default templates. This essentially mimics how Iron-Router was using template defaults in Router.config(), with the added benefit of local route template definitions not overwriting the whole default template object.

  • UPDATE The above has worked well for me, although I did end up having another problem which I had to solve to make it work consistently.

Essentially, if you modify any underlying "route defaults" as we are doing, in the local route.action function, since Flow-Router is non-reactive, the router group object seems to persist from route to route as long as the routes are in the same group. Also this "options" object is passed to the router from the route definition. So what this means is that if you override a default parameter in the case above, it will be overwritten for all subsequent routes using that same group, after the route that overrides it is called.

The solution I came up with was to do a defaults reset function as so: triggersExit: [ resetDefaults ] in the group definition.

Then is just do a resetting of defaults. The reason I did it on exit is so that the next route being called can still override locally these defaults:

function resetDefaults (context) {
  context.route.group.options.defaultLayoutTemplate = "mainAppLayout";
  context.route.group.options.defaultTemplates = {
    defaultTeamplates: "navMain",
    // ...
};


来源:https://stackoverflow.com/questions/37858901/a-good-way-to-define-default-rendering-templates-in-flowrouter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!