0

My EmberJS app has a couple of actions (triggered by buttons) that require a view/DOM manipulation as well as setting a state in the controller, followed by a model update. The way I do this, it does not appeal to my programming aesthetics. It gets the job done, but it doesn't look good :(

Here is a gist of how I do things :

<button {{action 'whatever' target='view'}}></button>

App.MyView = Ember.View.extend({

   actions:{
       whatever:function(){
         var ctrl = this.get('controller');
         ctrl.set('property',value); // arbitrary example of setting a controller property through it's view
         ctrl.controllerMethod(); // invoking a controller method through the view
         **// do some DOM manipulation**  
       }
   }    
});

Naturally, I can wrap whatever controller related steps I am performing in the view in a controller method and invoke that method through the view, but IMO that's just equally ugly. The view shouldn't really be invoking a controller method like how I have done. Unfortunately, this specific action requires a DOM manipulation as well as setting some state and performing an action in the controller.

I am not sure what is the recommended way of performing this. Can anyone enlighten ?

Parijat Kalia
  • 4,929
  • 10
  • 50
  • 77
  • 2
    Can you describe the DOM manipulation? Ideally the DOM change would be triggered by databinding because controller state has changed. – Luke Melia Feb 03 '14 at 03:08
  • very interesting, so essentially something like this: 'add' or 'remove' a view. These views are part of a collection view that is backed by an array controller. State is being set in an array controller. The views are generated dynamically by the content available in the array controller. Please note: When the state is set in array controller, the content is not removed or added. – Parijat Kalia Feb 04 '14 at 21:23
  • I don't completely follow; perhaps you could make a jsbin to illustrate? – Luke Melia Feb 05 '14 at 03:16

2 Answers2

1

I suggest you handle the action from the controller. I noticed you're setting a property. You can use that to signal something to the view and then do the DOM manipulation within the view.

App.MyView = Ember.View.extend({
   function () {
     **// do some DOM manipulation**  
   }.observe('controller.property'); 
});

The way I think about it is that UI 'actions' are mapped to a business event (e.g. addClient instead of click), then as a result of that something happens that could change properties of the model, controller. As a result of those changes the view might need to update directly, ideally through a binding, but sometimes is needed to modify the DOM manually.

Miguel Madero
  • 1,948
  • 13
  • 21
0

as @LukeMelia said in his comment you should really handle the changes in your controller and update your view (if you need to?) via databinding.

so, you would just omitt the target="view" argument from your view helper and Ember will look for the proper action in the nearest controller, bubbling all the way up to the route, and so on.

a simple code snippet (with what you provided in your first post) would look like:

Handlebars Template:

<button {{action someAction}}>Fire!</button>

Ember.Controller:

App.MyController = Ember.ObjectController.extend({
  myProperty: 'cool',

  printMyCoolness: function () {
    console.log("I'm using Ember.js!");
  },

  actions: {
    someAction: function () {
      this.set('myProperty', 'set on fire!');
      this.printMyCoolness();
    }
  }
});
herom
  • 2,532
  • 29
  • 41
  • thanks @herom . However the above solution is pretty basic, I arrived @ target = "view" when I realized that this task required back n forth between the controller and the view. – Parijat Kalia Feb 05 '14 at 19:15