mpj
mpj

Reputation: 5367

Ember.js - Binding to another controller's model

In my project, I have the following three models:

Club

var Club = DS.Model.extend({
    ... bunch of properties ...

    clubmeta: DS.belongsTo('App.Clubmeta'),
    customCourts: DS.hasMany('App.CustomCourt')
});

module.exports = Club;

Clubmeta

var Clubmeta = DS.Model.extend({
    ... bunch of properties ...
    customCourtsEnabled: DS.attr('boolean'),

    club: DS.belongsTo('App.Club')
});

module.exports = Clubmeta;

CustomCourt

var CustomCourt = DS.Model.extend({
    name: DS.attr('string'),
    glass: DS.attr('boolean'),
    indoor: DS.attr('boolean'),
    single: DS.attr('boolean'),

    club: DS.belongsTo('App.Club')
});

module.exports = CustomCourt;

What I need to do is a template where the club (which is the logged in user) can add customCourts only if clubmeta.customCourtsEnabled is true. As I was told in another SO question, I should be using an ArrayController to handle CustomCourts.

Everything is ok until this point, the problem comes because CustomCourtsController needs to know about club and clubmeta. I have tried this, with some variations to the binding path:

var ClubCourtsController = Ember.ArrayController.extend({
        needs: ['currentClub'],
        customCourtsEnabledBinding: Ember.Binding.oneWay("App.currentClubController.content.clubmeta.customCourtsEnabled"),
        ...
});

CurrentClubController

var CurrentClubController = Ember.ObjectController.extend({
    init: function() {
        this._super();
        console.log('Retrieving club ' + App.clubId);
        this.set('content', App.Club.find(App.clubId));
    }
});

module.exports = CurrentClubController;

But ClubCourtsController.customCourtsEnabled always returns undefined. What is the right way to do this?

Upvotes: 0

Views: 1985

Answers (2)

Mike Grassotti
Mike Grassotti

Reputation: 19050

ClubCourtsController.customCourtsEnabled always returns undefined. What is the right way to do this?

You're on the right track. For starters the right way to do the binding is via the controllers property:

var ClubCourtsController = Ember.ArrayController.extend({
    needs: ['currentClub'],
    customCourtsEnabledBinding:     Ember.Binding.oneWay("controllers.currentClub.clubmeta.customCourtsEnabled"),
});

Beyond that, it's generally best practice to wire things together in your route's setupController hook instead of a controller init. So even if you've got that binding right, could be other issues causing the customCourtsEnabled property to be undefined. I've posted a working example on jsbin here: http://jsbin.com/ubovil/1/edit

App = Ember.Application.create({
  clubId: 1
});
App.Router.map(function() {
  this.route("customCourts", { path: "/" });
});
App.Club = Ember.Object.extend({});
App.Club.reopenClass({
  find: function(id) {
    return App.Club.create({
      id: id, 
      clubmeta: App.ClubMeta.create({
        customCourtsEnabled: true
      })
    });
  }
});
App.ClubMeta = Ember.Object.extend({});
App.CurrentClubController = Ember.ObjectController.extend({});

App.ApplicationController = Ember.Controller.extend({
  needs: ['currentClub']
});

App.ApplicationRoute = Ember.Route.extend({
  setupController: function(controller) {
    controller.set('controllers.currentClub.content', App.Club.find(App.clubId));
  }
});

App.CustomCourtsController = Ember.ArrayController.extend({
  needs: ['currentClub'],
  customCourtsEnabledBinding: Ember.Binding.oneWay("controllers.currentClub.clubmeta.customCourtsEnabled")
});

App.CustomCourtsRoute = Ember.Route.extend({
  setupController: function(controller) {
    controller.set('content', ['Court a', 'Court b', 'Court c']);
  }
});

Upvotes: 2

Bradley Priest
Bradley Priest

Reputation: 7458

You need to access the controller via the controllers property

ClubCourtsController = Ember.ArrayController.extend({
  needs: ['currentClub'],
  customCourtsEnabledBinding: Ember.Binding.oneWay("controllers.currentClub.clubmeta.customCourtsEnabled"),
  ...
});

Upvotes: 1

Related Questions