1
votes

I have a component that is a button which needs to change it's classNames via a property of it parent component/controller:

// components/my-button/component.js
import Ember from 'ember';

export default Ember.Component.extend({
    tagName: 'button',
    classNameBindings: ['classNames'],
    // some other unrelated stuff following....
});

it's template:

// components/my-button/template.hbs
{{text}}
// nothing important here exept the test-output of:    
{{classNames}}

and I insert it like this in another component:

// component/parent-component/template.hbs
{{my-button
    classNames=variableClassNames
    text='foo'
}}


// components/parent-component/component.js
import Ember from 'ember';

export default Ember.Component.extend({

    isSortableDown: Ember.computed('track.sort', 'maxSort', function() {
        return this.get('track.sort')<this.get('maxSort');
    }),

    variableClassNames: Ember.computed('isSortableDown',function() {
        if(this.get('isSortableDown')) {
            return 'btn btn-xs btn-default';
        } else {
            return 'btn btn-xs btn-default push-20-r';
        }
    }),

    // other unrelated stuff...
});

Now here's my problem:
when isSortableDown is changing, variableClassNames in parent AND classNames in child (component/my-button) IS updated (also the test-output in my-button template).
BUT the classNameBindings are NOT updated, instead the classNames appear multiple times (when looking at the actual outputted DOM). Well, that's not 100% right, they do get added, but never removed.
So if the className push-20-r once gets added, it'll stay there (in the DOM), but never removed, even if the property classNames doesn't include it anymore.

Finally my question is if I'm doing something wrong,
or if the classNameBindings should not be updated (but why the name 'bindings' then??),
or if this is eventually a bug?

I'm on
Ember 2.0.1
jQuery 1.11.3

The only maybe relevant issues I found are:
https://github.com/emberjs/ember.js/issues/11980
https://github.com/emberjs/ember.js/issues/11556
but they don't have an answer... or are only party related

Sidenote: Yes, I want the component itself to be a button, not a div, because otherwise I'd have to change all the css.... I know I could do it by leaving the component a div and wrap that button and adjust it's classNames there.

2

2 Answers

2
votes

classNames is a special property within components. You might try changing the name to something else and see if that helps?

http://emberjs.com/api/classes/Ember.Component.html#property_classNames

2
votes

you are using special property of ember component classNames as bound variable which was causing the problem instead you can take following approach

export default Ember.Component.extend({
    tagName: 'button',
    classNameBindings: ['isSortableDown::push-20-r'], // class added when isSortableDown is false 
    classNames: ['btn', 'btn-xs', 'btn-default'], // classes that don't change
    isSortableDown: true
    // some other unrelated stuff following....
});

in template

{{my-button
    isSortableDown=isSortableDown
    text='foo'
}}

in your parent component

export default Ember.Component.extend({

    isSortableDown: Ember.computed('track.sort', 'maxSort', function() {
        return this.get('track.sort')<this.get('maxSort');
    }),

    // other unrelated stuff...
});