New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Make a simplified routing solution #4448

Open
phillipskevin opened this Issue Aug 31, 2018 · 5 comments

Comments

Projects
None yet
3 participants
@phillipskevin
Copy link
Collaborator

phillipskevin commented Aug 31, 2018

This was discussed on a recent live stream (29:28) and a previous live stream.

This proposal is to make it easier to configure which component should be displayed for each route.

This will need to

  • map each route to the correct component
  • map each route to the viewmodel data required by the component
  • support nested routes
  • support progressive loading
  • support "two-way" routing (if possible)

Related Proposals: #3833

One possible solution is a configuration like this:

import { Component, router } from "can";
import HomePage from "./pages/home";

const routes = {
    "{page}": {
        home: {
            // statically imported page
            Component: HomePage,
            data: {
                logout: "logout"
            }
        },
        login: {
            // lazy loaded page
            Component: () => import("./pages/login"),
            data: {
                isLoggedIn: "isLoggedIn"
            }
        },
        tasks: {
            "{taskId}": {
                Component: () => import("./pages/tasks"),
                data: {
                    logout: "logout",
                    id: "{taskId}"
                }
            }
        },
        "default": {
            // custom HTML page
            Component: () => {
                var page404 = document.createElement("h2");
                page404.innerHTML = "Page Missing";
                return page404;
            }
        }
    }
};

const router = new Component({
    tag: "my-app",

    view: `
        {{pageComponent}}
    `,

    ViewModel: {
        pageComponent: router(routes),
        isLoggedIn: { default: false, type: "boolean" },
        logout() {
            this.isLoggedIn = false;
        }
    }
});
@phillipskevin

This comment has been minimized.

Copy link
Collaborator

phillipskevin commented Aug 31, 2018

One thing that would need to be figured out is how to handle Sessions. One way to do this is to let the router also create virtual properties based on other ViewModel properties. This way the "{page}" property used to decide the active route could be set based on the user's Session:

router(routes, {
    get page(lastSet) {
        if (!this.isLoggedIn) {
            return "login";
        }
        return lastSet;
    }
})

Not sure I love this.

@phillipskevin

This comment has been minimized.

Copy link
Collaborator

phillipskevin commented Sep 14, 2018

This could also make it so that a new component is not created if taskId changes for a route like this:

        tasks: {
            "{taskId}": {
                Component: () => import("./pages/tasks"),
                data: {
                    logout: "logout",
                    id: "{taskId}"
                }
            }
        },

Since the Tasks component will be internally using something like viewModel: { id: value.from(this.routeData, "taskId") }, a new Component does not need to be created for this case.

@frank-dspeed

This comment has been minimized.

Copy link
Contributor

frank-dspeed commented Oct 15, 2018

I think this should get avoided !!!
component.mjs

let myComponent = Component.extend
export myComponent as Component

index.mjs

var data = {}
import('./component.mjs').then(({Component})=>new Component(data))

this is total ok and needs no addition i think

@frank-dspeed

This comment has been minimized.

Copy link
Contributor

frank-dspeed commented Oct 15, 2018

i think the way to go is let the people code custom routers and gives them a example because the init tasks of every component are really diffrent

@chasenlehara chasenlehara changed the title Proposal: Make it easier to map Routes to Components Proposal: Make a simplified routing solution Nov 16, 2018

@eben-roux

This comment has been minimized.

Copy link
Contributor

eben-roux commented Nov 20, 2018

I haven't quite read all the documentation so perhaps I'm stating some obvious bits here but let me do it anyway :)

The type of routing I use in my solutions is convention-based. There is also a permission system built in but that type of thing can be done using a callback on some configuration.

The gist of it is that there is a list of resources that represent the various routes and the content/properties of that resource determine what the actual route will be created as.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment