Search code examples
ember.jscontrollermodelsember.select

Ember.js: How to set default options of multiple Ember.Select(s) in a single controller?


This is my first Ember.js application. All Ember's examples and tutorials I found are a single controller with a single model or a single model having children models. However, this application puts two models (companies and users) into a single controller (login) side by side. However it doesn't work very well.

enter image description here

Its jsbin.com code is at: jsbin.com/cirah

My design is: the login controller doesn't have a defined model, but two arrays of companies and users. Each of both has an _selid to indicate the current selection.

window.App = Ember.Application.create({});
App.ApplicationStore = DS.Store.extend({
    adapter: 'App.ApplicationAdapter',
});
App.ApplicationAdapter = DS.RESTAdapter.extend({
    host: 'http://emberjs.azurewebsites.net',
    headers: {
        "Accept": "application/json",
    }
});
App.Company = DS.Model.extend({
    company: DS.attr('string')
});
App.User = DS.Model.extend({
    userName: DS.attr('string'),
    passwordHash: DS.attr('string'),
});
App.Router.map(function () {
    this.resource("login", { path: '/login' });
});
App.IndexRoute = Ember.Route.extend({
    redirect: function () {
        this.transitionTo('login');
    },
});
App.LoginRoute = Ember.Route.extend({
    setupController: function (controller, model) {
        var store = this.get('store');
        controller.set('companies', store.find('company'));
        controller.set('company_selid', 2);
        controller.set('users', store.find('user'));
        controller.set('user_selid', 3);
    },
});
App.LoginController = Ember.ObjectController.extend({
    companies: null,
    company_selid: '2',
    users: null,
    user_selid: '3',
    passwordHash: '',
    actions: {
        login: function () {
            alert('login clicked');
        },
    },
});

The login template contains two Ember.Select(s) for the arrays.

<div class="input-group">
    <label for="company" class="input-group-addon ">Company:</label>
    {{view Ember.Select 
        class="form-control" 
        content=companies 
        optionValuePath="content.id"  
        optionLabelPath="content.company" 
        value="company_selid" 
        selectionBinding="company_selid"}}
</div>

<div class="input-group">
    <label for="userName" class="input-group-addon">User Name:</label>
    {{view Ember.Select
        class="form-control"
        content=users
        optionValuePath="content.id"
        optionLabelPath="content.userName"
        value=user_selid
        selection=user_selid
    }}
</div>

The server side returns:

http://emberjs.azurewebsites.net/companies?format=json
{"companies":[
    {"id":1,"company":"ABC Company"},
    {"id":2,"company":"XYZ Company"}
]}
http://emberjs.azurewebsites.net/users?format=json   
{"users":[
    {"id":101,"userName":"Aaron","passwordHash":""},
    {"id":102,"userName":"Brian","passwordHash":""},
    {"id":103,"userName":"Corey","passwordHash":""},
    {"id":104,"userName":"David","passwordHash":""}
]}

My questions are:

Q1: What's the Ember's best practice to use single controller to embed multiple models? I'd like to have eager loading of two arrys, should I use Ember.RSVP in login model? Or should I use ContainerView?

Q2: In my code, the default options of two Ember.Select(s) doesn't work, it's always the 1st option, even I set them twice in login controller and setupController. How to fix it?

Thanks


Solution

  • You're on the right track.

    For loading the data I would load all the data in the model hook using Ember.RSVP.hash to return an object with all the data you need loaded, and then you can set the correct elements in the controller in setupController.

    As for the Ember.Selects the reason why it was not selecting the correct item was because you were not setting the value correctly.

    There is 2 ways to get the currently selected item from an Ember.Select

    1. using the value attribute
    2. using the selection attribute

    The value attribute gets or sets the selection by it's value.
    The selection attribute gets or sets the the selected element of content.
    Since they represent 2 different things they should never be bound to the same property on your controller.

    In your case the value would be the selected model.id and the selection would be the entire model.

    Being that you wanted to set the selection using the id you would need to bind company_selid and user_selid to the value property of the Ember.Select.
    One thing to look out for when using ember data is that ember data will create the models with the id as a string, so when setting the company_selid you need to set it as string.

    I setup a working bin here: http://jsbin.com/gaduve/1/edit