manidos
manidos

Reputation: 3464

Router issue with m.route.link

While playing around with Mithril I stumbled upon this issue and I'm not sure if it's a bug or a feature or I'm doing something wrong.

Please, run the script below and click on View Two and then on Link three. You'll see that the console outputs "RENDER TWO" each time you click on Link three. It doesn't make any sense, because in the code link component has neither href nor oncreate: m.route.link specified. It's as if it inherits it from the previous route or something. Also, if I remove onclick handler everything works as expected(console outputs nothing).

I've also opened an issue on github. If you feel you can help fix it please go here.

Anyway, do you have any idea what's going on?

const outlet = document.body;

//COMPONENTS
class Link {
  view(vnode){
    return m('a', vnode.attrs, vnode.attrs.title);
  }
}
class ViewOne {
  view(vnode){
    return m('div', 'view one');
  } 
}
class ViewTwo {
  view(vnode){
    return m('div', this.getLinkThree());
  } 
  getLinkThree(){
    return m(Link, {
      title: 'Link three',
      onclick: () => {} // removing this handler solves the problem (routerResolver's render not invoked)
    });
  }
}

//HELPERS
const getLinkOne = () => {
  return m(Link, {
    title: 'View One',
    href: '/one',
    oncreate: m.route.link
  });
}
const getLinkTwo = () => {
  return m(Link, {
    title: 'View Two',
    href: '/two',
    oncreate: m.route.link
  });
}
const getViewHolder = () => {
  return m('#view-holder');
}

//INIT
m.render(outlet, [
  getLinkOne(), 
  getLinkTwo(),
  getViewHolder()
])
m.route(document.getElementById('view-holder'), "/one", {
  "/one": {
    render: () => {
      console.log('RENDER ONE');
      return m(ViewOne);
    }
  },
  "/two": {
    render: () => {
      console.log('RENDER TWO'); //also logs when clicking on 'Link three'
      return m(ViewTwo);
    }
  }
})
a {
  padding: 5px;
  background-color: grey;
  margin-right: 5px;
}
#view-holder {
  width: 200px;
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: lightgrey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/mithril/1.1.1/mithril.min.js"></script>

Upvotes: 1

Views: 323

Answers (1)

pakx
pakx

Reputation: 236

Eugene, this is expected Mithril 1.x behavior: triggering a ui-event handler causes a vdom build + diff.

Separately it's ... unusual ... to have both m.render() and m.route() calls as part of setup. In this case just m.route() suffices. Pls see here (you'll need to prefix the following short-link with "https://"): goo.gl/z8rZFf

BTW the above leads to an editor called "Flems" -- it encodes file references, in-situ code, etc into the URL, so to share a Flems just copy/paste its URL. This has the advantage of being able to share work without creating physical resources such as w/ JSBin, etc, but a downside is that in most cases the URL needs to be shortened to be share-able.

Upvotes: 1

Related Questions