0

This question is linked to the answer given here.

Having a checkbox in a view

App.RoleCheckbox = Em.Checkbox.extend({
    userRolesBinding: 'parentView.user.roles', // Points to the roles of the user

    checked: function () {
        var userRoles = this.get('userRoles');
        return userRoles.contains(this.get('content'));
    }.property('content', 'userRoles.@each'),

    click: function (evt) {
        //do something
        var controller = this.get("controller");
        controller.clicked(evt);
     }
});

I would like that the click function calls the clicked function from the RoleCheckboxController:

App.RoleCheckboxController = Em.Controller.extend({
    clicked: function(evt){
        //Really do the thing
    }
});

But this does not work. How could I fix this ?

JSFiddle: http://jsfiddle.net/3fMpD/

3 Answers 3

1

You can instantiate and associate the controller to the view using the correct naming conventions.

For example, this would associate the controller to the view:

// Instead of App.RoleCheckBoxController
App.ApplicationController = Ember.Controller.extend( /* ... */ );
App.ApplicationView = Ember.View.extend( /* .. */ );

JSFiddle: http://jsfiddle.net/YL5rQ/

Sign up to request clarification or add additional context in comments.

4 Comments

thank you, it clarified things to me. I edited your answer to show part of your jsfiddle code
Another question: I don't understand the bindings you use. Which doc or tutorial should I read to get a better understanding of userRolesBinding, ... you used ? I am not able to re-use this as a subview of another app
I think the edit was not approved for some reason. And there are two userRolesBinding in my answer: userRolesBinding: 'parentView.user.roles' (which is detailed here) and userRolesBinding: 'user.roles' which is a simple binding.
Well, I thought I had made a copy paste from your jsFiddle. Maybe I missed something. Thank you for the links about bindings, I am beginning to understand how they work now.
1

@c4p is definitely right and the problem there is that your controller is not being created, and furthermore App.RoleCheckbox has no way of knowing it should use App.RoleCheckboxController as its controller.

I am not quite sure if this is the most Ember-y way of doing this but you can set the controller in the init (constructor function) of the Checkbox view, and then just make sure you send to the controller all the properties it needs to work with:

App.RoleCheckbox = Em.Checkbox.extend({

    init: function(){
      this._super();
      this.set('controller', new App.RoleController());  
    },

    userRolesBinding: 'parentView.user.roles',

    checked: function () {
        var userRoles = this.get('userRoles');
        return userRoles.contains(this.get('content'));
    }.property('content', 'userRoles.@each'),

    click: function (evt) {
        this.get('controller').send('clicked',this.checked, this.content);
     }
});

And the controller's code (just changing the parameters used in the function);

App.RoleCheckboxController = Em.ObjectController.extend({
    clicked: function(checked,role){

         var userRoles = App.User.roles;

         console.log("userRoles = ", userRoles);
         console.log("role = ", role);
         console.log("will be: ", !checked ? "removed" : "added");

         if (checked) { 
             userRoles.pushObject(role); 
         } else {
             userRoles.removeObject(role);
         }

         console.log("updated userRoles = ", userRoles);

    }
});

Working fiddle here: http://jsfiddle.net/cfSwq/3/

Hope this helps!

1 Comment

Thanks, it helped me in the understanding of this. I don't know if it is possible to re-use an existing instance of an object, that would be a best approach, but this one seems fine to me.
0

Your App.RoleCheckboxController is never created. The way you have things set up there will only be an instance of ApplicationController.

You can move the logic back into the view's click event to have everything work:

App.RoleCheckbox = Em.Checkbox.extend({
    userRolesBinding: 'parentView.user.roles',

    checked: function () {
        var userRoles = this.get('userRoles');
        return userRoles.contains(this.get('content'));
    }.property('content', 'userRoles.@each'),

    click: function (evt) {
        console.log("event triggered:", evt);
        //var controller = this.get("controller");
        //controller.clicked(evt);
        var isPresent = this.get('checked'),
            userRoles = this.get('userRoles'),
            role = this.get('content');

         console.log("userRoles = ", userRoles);
         console.log("role = ", role);
         console.log("will be: ", isPresent ? "removed" : "added");

         if (!isPresent) { 
             userRoles.pushObject(role); 
         } else {
             userRoles.removeObject(role);
         }
     }
});

Updated JSFiddle

1 Comment

Actually, what you wrote is the original solution I had (see the first link of my question). I would like to put the business logic (the part inside the click function) in a controller's function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.