emberjs / ember.js

Ember.js - A JavaScript framework for creating ambitious web applications
https://emberjs.com
MIT License
22.47k stars 4.21k forks source link

Can't specify class attribute on tag-less components #12258

Closed olivierlesnicki closed 9 years ago

olivierlesnicki commented 9 years ago

When tagName is specified as an empty string an error is thrown whenever I attempt to define a class property on the component:

// my-button.js
import Ember from 'ember';
export default Ember.Component.extend({
  tagName: '',
  class: '',
  actions: {
    action() {
     this.sendAction(...arguments);
    }
  }
});
{{!-- my-button.hbs --}}
<button class="{{class}}" action="action">{{yield}}</button>
{{!-- my-route.hbs --}}
{{my-component class="foo bar"}}

While it's logical classNameBindings won't work for a tag-less component I think preventing developers to overwrite a property named "class" is a mistake.

rwjblue commented 9 years ago

Adding any attribute that would normally affect a standard tagged component's element should result in an error when used on a tag less component.

We should also add an assertion if we detect event handlers (I.e. click function in the root of the component).

This is to help prevent situations where folks do not fully understand what a tagless component is, and expect events and/or element attributes to somehow work when there is no element.

olivierlesnicki commented 9 years ago

@rwjblue Shouldn't a warning be enough? The errors are limiting for the folks who do understand tag-less components.

After experimenting with React for the past few months, I can't help but think that tag-less components should be the de facto solution.

What would be the recommended way to implement the above example? It seems component with button tagNames do not inherit button views behaviors (namely the default action).

rwjblue commented 9 years ago

The upcoming Ember.GlimmerComponent feature will allow us to remove special scenarios for most/all of the current JS API's for managing a component's own element. For example, attributeBindings, classNames, classNameBindings, class added to the component's JS definition are not used in any way.

What would be the recommended way to implement the above example?

I am not 100% sure of your question, but questions on how to do something are generally better suited for Stack Overflow. I do not see any errors when attempting your intro/setup so I'm going to go ahead and close the issue. I am happy to reopen if you can demonstrate this as a bug though.

Demo: http://emberjs.jsbin.com/wacuxu/edit?html,js,output

olivierlesnicki commented 9 years ago

Strange, thanks for your time, will provide more details when/if I can replicate the issue