0

Hey I'm facing a problem with removing a view.

The view is used as navbar

{{view "inner-form-navbar" navbarParams=innerNavObject}}

Where params look like this

 innerNavObject: {
        ...
        routeToReturn: 'someroute.index',
        ...
 },

On the navbar there's a small "back" button when it's clicked the parent index route is opened.

It currently works like this:

this.get('controller').transitionToRoute(routeToReturn);

But this won't work in a component and is sketchy anyways. Do i need to somehow inject router to component? Or has anyone gotten a solution for this? The navbar is used in so many places so adding a property to navbarObject to have certain action defined is not a really good solution imo.

Went for this solution :

export default {
    name: 'inject-store-into-components',
    after: 'store',
    initialize: function(container, application) {
        application.inject('component', 'store', 'service:store');
        application.inject('component', 'router', 'router:main'); 
    }
};

Now i can do

this.get('router').transitionTo('blah')
kristjan reinhold
  • 2,038
  • 1
  • 17
  • 34

2 Answers2

1

Well you can try to use a service that provides the routing capabilities and then inject into the component.

There's an addon that seems to do just that - ember-cli-routing-service

Example taken from the link, adapted for you scenario:

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

 someFunc () {
   this.get('routing').transitionTo(this.get('innerNavObject'). routeToReturn);
 } 
});
Pedro Rio
  • 1,444
  • 11
  • 16
0

Having a component control your route/controller is typically bad practice. Instead, you would want to have an action that lives on your route or controller. Your component can then send that action up and your route or controller will catch it (data down, actions up).

In your controller or route, you would have your transition action:

actions: {
  transitionFunction(route) {
    this.transitionTo(route);
  }
}

You would also define the the current route name in your route or controller and pass that to your nav bar component. Controller could then look like:

export default Controller.extend({
  application: inject.controller(),
  currentRoute: computed('application.currentRouteName', function(){
    return get(this, 'application.currentRouteName');
  }),

  actions: {
    transitionFunction(route) {
      this.transitionTo(route);
    }
  }
});

Then call your component and pass the currentRoute CP to it:

{{nav-bar-component currentRoute=currentRoute action='transitionFunction'}}

Then, in your component, you can have a function that finds the parent route from the currentRoute:

export default Component.extend({
  click() { // or however you are handling this action
    // current route gives us a string that we split by the . and append index
    const indexRoute = get(this, currentRoute).split('.')[0] + '.index';
    this.sendAction('action', indexRoute);
  }
});

Extending a route

Per your comment, you may want to have this across multiple routes or controllers. In that case, create one route and have your others extend from it. Create your route (just as I created the Controller above) with the action. Then import it for routes you need:

import OurCustomRoute from '../routes/yourRouteName';

export default OurCustomRoute.extend({
  ... // additional code here
});

Then your routes will have access to any actions or properties set on your first route.

sbatson5
  • 648
  • 11
  • 19
  • I know that i would want this. but this is not gonna work for me. Having 68 matches across 68 files. Im not gonna write each route that small action snippet – kristjan reinhold Nov 18 '15 at 06:40
  • Basically it seems like too much muscle for something semantically correct =D – kristjan reinhold Nov 18 '15 at 06:56
  • @kristjanreinhold you can have 1 route and have each other route extend it, therefore granting access to this action without having to duplicate it everywhere. – sbatson5 Nov 18 '15 at 13:45