2

I've just started learning Aurelia JS, and I bumped into a problem.

I have my routes in app.js as:

  configureRouter(config, router){
    config.title = 'TEST';
    config.map([
      { route: ['','main'], name: 'main', moduleId: './mainpage', nav: true, title:'Main' },
      { route: 'info',     name: 'info', moduleId: './info', nav: true, title:'Info' }
    ]);

    this.router = router;
  }

If, in mainpage.html, I use this:

<div class="button" route-href="route: info;">Go to Info</div>

... then nothing happens; if I also add:

<div class="button" route-href="route: info;" click.trigger="route: info;">Go to Info</div>

... then I get a crash of au run. However, if I use the <a> element instead:

<a route-href="route: info;"><div class="button">Go to Info</div>

... then routing/navigation on click works fine - but my CSS style is completely messed up; and I'd rather not style <a> specifically for this.

So first question:

  • Is it possible to navigate to a route from a <div> element; and if so, how?

I also tried executing this directly from JavaScript (as per Aurelia.io: how to navigate to route, see also Error: ENOENT: no such file or directory src/aurelia-configuration.js · Issue #64 · Vheissu/aurelia-configuration · GitHub); so in mainpage.html I have this:

<div class="button" click.trigger="goInfo()">Go to Info</div>

And in mainpage.js

import { Router } from 'aurelia-routing';

//~ @inject(Router)
export class Main {
  static inject() { return [Router]; }

  constructor(router) {
    this.router = router;
  }

  goInfo() {
    alert("Go Info");
  }
}

The @inject(Router) fails with something like inject not being found, so I used the static.. syntax as in the tutorial.

As long as I don't have the import { Router } from 'aurelia-routing'; part, then I can see goInfo() fires upon div click, and alert shows. But as soon as I add the aurelia-routing part, I get:

...
{ uid: 11,
  name: 'writeBundles',
  branch: false,
  error:
   { [Error: ENOENT: no such file or directory, open '[full project path]/src/aurelia-routing.js']
     errno: -2,
     code: 'ENOENT',
...

... and I've even added to aurelia_project/aurelia.json:

...
        "dependencies": [
...
          "aurelia-route-recognizer",
          "aurelia-router",
          {
            "name": "aurelia-router",
            "path": "../node_modules/aurelia-router/dist/commonjs",
            "main": "index"
          },
          "aurelia-task-queue",
...

... but still I get "file not found"... Somehow, the import still insists on finding a file in src/, even if that file is in node_modules/aurelia-router/

So second question is:

  • How can I execute/navigate to a route from JavaScript? Note, I would rather not work via the URL (as in location.assign('#/info');)

EDIT: Just found out it is not called aurelia-routing anymore, as in the mainpage.js code snippet which I copied from elsewhere - but it is called aurelia-router now, as the aurelia.js shows. So I just changed the import in mainpage.js to import { Router } from 'aurelia-router'; - and then you do not need the insert between curly braces { (the "name": "aurelia-router",... part) in aurelia.js - and then this.router.navigateToRoute("info"); works in mainpage.js's goInfo() for navigation.

I'd still like to know if it is possible to get a click on a div to navigate using routing with just an attribute, instead of a separate JS function... EDIT2: possibly relevant: Aurelia delegate vs trigger: how do you know when to use delegate or trigger? :

Only events that bubble can be used with Aurelia's delegate binding command. The blur, focus, load and unload events do not bubble so you'll need to use the trigger binding command to subscribe to these events. ...
iOS does not bubble click events on elements other than a, button, input and select. If you're subscribing to click on a non-input element like a div and are targeting iOS, use the trigger binding command. More info here and here.

Community
  • 1
  • 1
sdbbs
  • 4,270
  • 5
  • 32
  • 87
  • You should probably update your button class so that it works on links too. No reason it should be tied to divs only. – powerbuoy Oct 29 '17 at 11:27

1 Answers1

11

The route-href custom-attribute generates a href attribute, which only works for <a>. It doesn't work for divs, because <div href="/page"></div> is not a valid markup.

To solve this problem, you could create your own custom-attribute. Something like this:

import { customAttribute, bindable, inject } from 'aurelia-framework';
import { Router } from 'aurelia-router';

@inject(Element, Router)
@customAttribute('go-to-route')
export class GoToRoute {

  @bindable route;
  @bindable params;

  constructor(element, router) {
    this.element = element;
    this.router = router;
  }

  attached() {
    this.element.addEventListener("click", () => {
      this.router.navigateToRoute(this.route, this.params);
    });
  }
}

Usage:

<template>
  <require from="./go-to-route"></require>
  <div go-to-route="route: somewhere; params.bind: someParams">Go To Somewhere</div>
</template>
try-catch-finally
  • 7,436
  • 6
  • 46
  • 67
Fabio
  • 11,892
  • 1
  • 25
  • 41