I want multiple variables toggled as true or false depending on the current route

I want multiple variables toggled as true or false depending on the current route, which the controller checks when the page loads.

VpcYeoman.SuperTableController = Ember.ArrayController.extend({  
    routedToLocations: false,
    routedToUsers: false,
    currentPath: '/',
    checkCurrentPath: function() {
      if ( currentPath == '/users')
        this.set( 'routedToUsers', true )
    } elsif ( currentPath == '/locations' ) {
        this.set( 'routedToLocations', true )
    }
});

superTable.hbs

{{#if routedToUsers}}
Users!
{{/if}}

{{#if routedToLocations}}
Locations
{{/if}}

in users.hbs

{{render superTable model}} //which will result in the string 'Users!'

in locations.hbs

{{render superTable model}} //which will result in the string 'Locations!'

Or maybe i could add the variables, like routedToUsers, inside of the 'users' controller with set values. It would look like,

- users_controller.js -
    routedToUsers: true,
    canBeEdited: false,
    canBeDeleted: true,

This way, each super-table has those variables except they are already predefined. Another example.

 - locations_controller.js - 
       routedToUsers: false, // this is obviously false but for example's sake
       routedToLocations: true,
       canBeEdited: false,
       canBeDeleted: false,

So if I clicked a #link-to on another page that routed me to 'users' for instance, the controller would use 'checkCurrentPath' to make sure that I was indeed on the users page.

Answers:

Answer

There are really two main groups of path changes or "transitions" that occur in your app.

First: Ember will initialize and the router will transition the user into the desired context. This can take several transitions if you have nested resources. If a user returns to a nested resource or reloads the page, Ember is smart and will reload with context. Thus, the auto-transitioning.

Second: The user may transition through the app based on whatever UI you cooked up.

To address the first of two issues, you will probably need to initialize each route's controller to activate the currentPath property, using the setupController hook. That way on page load the route will do the first setter, then the observer will deal with any user-based path changes.

Here is a generic path observer that you can place in your application controller. It will address the second of the two issues:

App.ApplicationController = Ember.Controller.extend({
  needs: ['super-table', 'users', 'locations'],
  currentPathDidChange: function () {
    var path_base = this.get('currentPath').split('.')[0];
    this.set('controllers.super-table.currentPath', path_base); // give your super table template the path
    this.nullifyActiveFlags(); // You can write this yourself...
    switch(path_base){ // just give me the base resource
      case 'users':
        this.set('controllers.users.activePath', true);
        break;
      case 'locations':
        this.set('controllers.locations.activePath', true);
        break;
    }
  }.observes('currentPath'),
//...

I would probably pull that callback logic out of the observer and into its own method, but this is just pseudo-code to show what is possible.

You should also refactor the super table currentPath setter to be a computed alias from within the super table controller.

Let me know if there is any additional explanation needed! I've used similar patterns quite a few times and it works very nicely when configured correctly.

Answer

To answer your question directly, undefined is falsey in Javascript, so you shouldn't actually need to explicitly set it to false. If you want a generic function to set the current path to true, just use regular expressions. For example:

setCurrentPath: function() {
  this.set(("routed_to_" + currentPath.match(/\/(.*)/)[1]).camelize(), true);
}

As a HUGE caveat, I'll also add you probably shouldn't be doing any of this in the first place. Generally, if you find yourself writing

if (isAThing) {
  ...
} else if (isAnotherThing) {
  ...
} else if (isYetAnotherThing) {
  ...
}

you might find the command pattern or chain of responsibility pattern useful.

Also, placing a lot of logic in Handlebars will eat away at your performance because every time something changes, it has to manipulate your DOM. If you need logic, keep it in Javascript and minimize the computed properties in your template. If it's more complex that that, let your router decide what to spit out into an outlet.

It's really tough to convey tone in text, and I hope I don't come across like I'm beating up on you. Just trying to pass on some hard-learned lessons. Good luck.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.