The Emberist

Ember.js and Related Technologies

Learn More About Ember.js emberjs.com

Absolute Paths in Classes

A common mistake I see in many Ember apps by new developers is the use of absolute paths in class definitions. In this post, I'll explain why this is bad and what you should do instead. Unlike some of the other areas I've address, this one isn't a technical issue, it's just a matter of good design.

Absolute Paths

Lets make sure we're clear on terminology here. When I say an absolute path, I mean a path that points to a global variable. In Ember such globals are usually distinguished by a capital first letter. For more information see my post on Naming Conventions.

What Not to Do

To help understand what I'm talking about, let me show you an example of what not to do.

JavaScript:

MyApp.currentUserController = Ember.Object.create({
  user: null
});

MyApp.UserView = Ember.View.extend({
  templateName: 'user',
  contentBinding: "MyApp.currentUserController.user"
});

HTML:

<script type="text/x-handlebars" data-template-name="user">
  {{content.name}}
</script>

<script type="text/x-handlebars">
  Current User: {{view MyApp.UserView}}
</script>

What's the Problem?

If you give this code a try, it does work, so why is this a bad idea? This is bad because it doesn't maintain a proper separation of concerns. The view class definition shouldn't have to know anything else about the structure of the app. It shouldn't have to know where the user value comes from. Furthermore, if you ever want to re-use UserView with a different value, you'll have to override the binding you already set up.

A Better Way

Hopefully, things will become even more clear with an example of a better way to do this.

JavaScript:

MyApp.currentUserController = Ember.Object.create({
  user: null
});

MyApp.UserView = Ember.View.extend({
  templateName: 'user',
  content: null
});

HTML:

<script type="text/x-handlebars" data-template-name="user">
  {{content.name}}
</script>

<script type="text/x-handlebars">
  Current User: {{view MyApp.UserView
                  contentBinding="MyApp.currentUserController.user"}}
</script>

What we did here is make UserView no longer care about where user is coming from. All it cares about is that it has a content with a name. In our app's root view, we make sure that we provide the correct user to the specific instance of the view instead of hardcoding it directly into the class definition. Not only have we separated our concerns, we've made our code more reuseable, since UserView is not longer locked down to just the current user. Keeping absolute paths out of your class definitions is a definite improvement.


blog comments powered by Disqus