Skip to content
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

autoMount and route settings order issue #158

Open
m-mujica opened this issue Feb 23, 2018 · 1 comment
Open

autoMount and route settings order issue #158

m-mujica opened this issue Feb 23, 2018 · 1 comment

Comments

@m-mujica
Copy link

m-mujica commented Feb 23, 2018

If routes are defined and used by an auto-mounted component, any setting to the route object need to be made before the component definition.

In the following example, when the component is mounted, route.bindings.pushstate.root points to its default value instead of /public/.

import Component from "can-component";
import route from "can-route-pushstate";
import DefineMap from "can-define/map/map";
import stache from "can-stache";

Component.extend({
  tag: "my-app",
  autoMount: true,
  ViewModel: DefineMap.extend({
    moduleId: "string",
    currentRule: function() {
      return route.currentRule();
    }
  }),
  view: `{{if currenRule() === "something"}}<sub-component>{{else}}404{{/if}}`
});

route.data = document.querySelector("my-app");

route.bindings.pushstate.root = "/public/";
route.register("/", { moduleId: "component-1" });
route.register("/component-2", { moduleId: "component-2" });

route.start();

What should we do in this case? Make route.bindings.pushstate.root observable so it broadcasts its value when changed?

@justinbmeyer
Copy link
Contributor

justinbmeyer commented Mar 5, 2018

This is a significant problem because automounted components are likely to mount with their default state which will not include the state from the URL. The following are some ways we could fix this:

WAY A: Turn off mounting for selected components

can.Component.extend({
    tag: "chat-app",
    view: `....`,
    automount: false // this component is not automounted
});

can.route.data = document.querySelector("chat-app");
can.route.ready() //-> can-route knows how to automount with data provided.  Likely something `can-view-callbacks` provides.

Pros:

  • relatively easy to follow

Cons:

  • more stuff to know ... this weird automount.

WAY B: Async mounting

Mount all components during a requestAnimationFrame. Code stays the same:

can.Component.extend({
    tag: "chat-app",
    view: `....`
});

can.route.data = document.querySelector("chat-app");
can.route.start();

Cons:

  • can-route would still need to know about can-view-callbacks to mount during start().
  • This would probably be a breaking change.

WAY C: init

Provide a way for components to define their initial data:

can.Component.extend({
    tag: "chat-app",
    view: `...`
    ViewModel: {
      init: function(){
        can.route.data = this;
        can.route.register("{page}",{page: "home"});
        can.route.ready()
      }
    }
})

Cons:

  • have to teach people init
  • APP VM not as easily test-able. Would want to mount like <chat-app initRouting:from="false"> and prevent the automount.

Questions:

  • connectedCallback would be better, but that gets called after the view is rendered. Do we need a more formal name?
  • Does can-element have this time when the viewModel is created but not the view?

Future thoughts:

  • We should get rid of calling .ready(). Once the data is assigned, it should be on.

Way D: cool bindings

<chat-app this:updateWith="scope.route"></chat-app>
// rules before component
can.route.register("...")

can.Component.extend({
    tag: "chat-app",
    view: `...`
    ViewModel: {
    }
});
  • when the route started to be listened to by anything (for example, the binding), we'd start looking at the url.
  • scope.route would need to be part of the scope. Provided by can-stache-route-helpers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants