7
votes

My task is to develop a menu component for an Ember 2 app. This is going to be a complex component whose visual representation changes as the user goes through routes. For instance it should disable particular menu and all its items when on "/index" route but enable it and some of its items when on "/details" and so on.

So, I've got a component that is passed a singleton model (stored in a Service currently, btw, is it a right place to store globally available singleton models in Ember?). It displays the stuff well but it does not respect the current route nor catches the route changes as user goes through the app. How can I achieve it?

Summing it up:

  1. The component needs to get current route somehow to be able to display its initial state, for instance the user bookmarked the "/details" page and visited it.
  2. The component has to deal with route changes somehow.
  3. Is a Service a good place to hold a singleton model (which could potentially be fetched from server).

Can you provide your thoughts on how to tackle the three above?

SOLVED: Ok, here's how it is done, thanks to @Bek's suggestions:

import Ember from "ember";

export default Ember.Component.extend({
    router: Ember.inject.service("-routing"),

    didInsertElement: function() {
        let r = this.get("router");
        console.log("Initial route", r.get("currentRouteName"));

        r.addObserver("currentRouteName", this, "currentRouteNameChanged");
    },

    "currentRouteNameChanged": function(router, propertyName) {
          console.log(router.get("currentRouteName"));
    }
});

MORE QUESTIONS :) - I had to surround the currentRouteNameChanged function name with quotes (to make it a string) otherwise it was not called. I assume I miss something very basic and obvious here?

One more issue is the funky service name -routing - @Bek, any hints on how could I figure it out myself, is there a list of injectable stuff I could look up information in? It is not yet in Ember documentation I assume but where in the source code of it to check it out? How stable -routing name in general, would it become *routing or something in final version?

1
you can do onRouteChange: Ember.observer('router.currentRouteName', function(){ console.log('route changed') }) to observe changes, or directly access router.currentRouteName in template to get current route nameBek
-routing is not documented so only way finding such things is going through ember.js source code :PBek
on r.addObserver... change to 'currentRouteNameChanged' and then in the function declaration you can use it without quotes.rafaelmorais

1 Answers

5
votes

Answer to 1 and 2: In latest versions of ember 2.x (in 2.2 at least) router is available as service so you can inject it to component router: Ember.inject.service('-routing') and observe changes on currentRouteName, but it is currently private service so should be used with caution as it might change (might be renamed to routing), there is also rfc https://github.com/emberjs/rfcs/pull/38 which proposes routable components which will be part of ember in the future.

Anser to 3: Services usually stateless, but there can be exceptions and services made to share global logic/objects so it is not a bad idea