samedi 25 avril 2015

Is this method of component communication an Ember anti-pattern?

Take this html and JS:

{{#main-view}}
  <!-- page html - header, content, etc. -->

  {{some-action tagName='button'}} Do it

  <!-- more page html -->

{{/main-view}}

// components/main-view.js

Ember.Component.extend({
  mainView: true,
  doSomething: function() { alert('doing something') }
})

// components/some-action.js

Ember.Component.extend({
  mainView: null,

  configureMainView: function() {
    this.set('mainView', this.nearestWithProperty('mainView');
  }.on('didInsertElement'),

  click: function() {
    this.get('mainView').doSomething(); 
  }
})

The idea so to have descendent components be able to interact with the interfaces of ancestors. A use case example could be you want the individual page content containers to be able to configure whether or not a hamburger menu is available on the page, like {{page-content show-menu='false'}}. This way you can simply define the menu at the top level and let children configure it as they need for their content.

I'm coming from the angular world, but it seems the more preferred way to handle this kind of thing in Ember is to bind to controller properties or handle actions in routes/controller actions at any appropriate level in the action bubbling. I can't help but feel that in many cases the controllers and routes have no business worrying about UI configurations, and so the related UI components should be able to simply communicate with each other and leave the controllers out of it.

Another pattern I've actually seen in ember-cli addons has been for children components to lookup and register themselves with a specific parent. And then the parent will call the interfaces of the children, or manipulate them however they see fit. Basically the same concept as above, just the opposite.




Aucun commentaire:

Enregistrer un commentaire