2
votes

I am currently working with Ember.js for a project at work - and though I seem to have got everything working, as in there are no errors, I am just trying to refactor the code as I feel I might be going about this wrong.

For the core set up of my Ember application, I have the following code which allows me to use a number of templates for the header and main section. The main section containing an outlet for me to connect my views to:

App.ApplicationView = Em.ContainerView.extend({
    childViews: [ 'headerView', 'mainView' ],
    headerView: Ember.View.create({
        tagName: 'header',
        ariaRole: 'banner',
        templateName: 'header'
    }),
    mainView: Em.ContainerView.create({
        elementId: 'wrapper',
        childViews: [ 'outletView' ],
        outletView: Ember.View.create({
            template: Ember.Handlebars.compile( '{{outlet}}' ),
        })
    })
});

I then set up my views. Stripped back for purposes of this post - and user model not included as this is pretty self-explanatory (userName set for testing purposes):

App.LoginView = Ember.View.extend({
    templateName: 'log-in',
    tagName: 'section',
    ariaRole: 'main'
});

App.LoginViewController = Ember.ObjectController.extend({
        content: App.User.create({ 'userName' : 'ben' })
});

I then have my router:

App.Router = Ember.Router.extend({
    root: Ember.Route.extend({
        index: Ember.Route.extend({
            route: '/',
            connectOutlets: function (router, context) {
                router.get('applicationController').connectOutlet('login');
            }
        })
    })
});

And my view:

<script type="text/x-handlebars" data-template-name="log-in">
    <h1>Sign In</h1>
    <p>Sign in using the form below.</p>
    <form id="log-in">
        {{view Ember.TextField valueBinding="userName" name="UserName" id="UserName" type="email" placeholder="[email protected]" required="required" }}
        {{view Ember.TextField valueBinding="userPassword" name="UserPassword" id="UserPassword" type="password" required="required" }}
        <input type="submit" value="Sign In" />
    </form>
</script>

My main issue is around the controllers, now from what I have been reading up on Ember.js this is how everything should be set up, however using the above code, my valueBindings are not working.

From what I can tell it is because my index route is using the applicationController, not my loginViewController. So if I change my controller to this:

App.ApplicationController = Ember.ObjectController.extend({
    user: App.User.create({ 'userName': 'ben' })
});

I can then access the object in my view by referencing user.userName fine, but then surely all my views are going to need to use the same controller - and that doesn't seem right to me. Surely each view should be using it's own controller?

If I change my router to connect to the loginViewController rather than applicationController - then the application breaks as my loginView does not contain an {{outlet}} paramater.

router.get('loginViewController').connectOutlet('login');

Am I missing something? It's driving me up the wall trying to get this perfect.

1
FYI, this question became out-of-date as of Spring 2013Luke Melia

1 Answers

1
votes

It's an issue with naming conventions. Try changing name of your controller to LoginController instead of LoginViewController.

under the hood, connectOutlet('login') will search the App namespace for a LoginView and LoginController classes. If controller is not found it just connects the view. So in your version the LoginView was being connected but LoginViewController ignored. LoginView was then rendering in context of ApplicationController, which is why things worked when you tried putting the user property there.

Also, best practice is to set controller content from within the connectOutlets callback. This should work:

App.LoginView = Ember.View.extend({
    templateName: 'log-in',
    tagName: 'section',
    ariaRole: 'main'
});

App.LoginController = Ember.ObjectController.extend({});
App.Router = Ember.Router.extend({
  root: Ember.Route.extend({
    index: Ember.Route.extend({
        route: '/',
        connectOutlets: function (router, context) {
            user = App.User.create({ 'userName' : 'ben' })
            router.get('applicationController').connectOutlet('login', user);
        }
    })
  })
});