vanthome
vanthome

Reputation: 4916

Ember JS Component combine three sources of CSS class names

I want to be able to write a component which has three sources of classNames:

Up to here I have tested successfully -- Ember will merge the two sources which I think is nice. I cannot however find where this behaviour is documented.

The only way to do this seems to be with classNameBindings but this is not sufficient in my case! As the list of classes is quite dynamic and I want to calculate it explicitly. What I have also tried is to define the classNames as property() but this seems not to be possible according to this issue.

Does anyone know a way to achieve this?

Upvotes: 1

Views: 866

Answers (2)

Microfed
Microfed

Reputation: 2890

I'm not sure I fully understood your reasoning against classNameBindings. You can get dynamic classes list with help of that property. I've prepared an example in jsbin.

It uses rule that applies to classNameBindings: if no conditional classes have been listed (eg. classNamesBindings: ['isEnabled:enabled:disabled']), than use provided by computed property class name as is (eg. true||false would be in classes list of HTMLElement). So, you need to declare a computed property which returns a string with classes names and to list this CP in component's classNameBindings.

Upvotes: 1

GJK
GJK

Reputation: 37369

This is one case where I think you don't want to use Ember and instead use jQuery directly. Use Ember to take care of the static classes and the classes provided through the Handlebars helper, but use jQuery to add the computed property classes. For instance, let's says that you have a computed property called extraClasses. Try something like this:

extraClasses: function() {
    return ['one', 'two', 'three'];
}.property(),

previousExtraClasses: [],

manageClasses: function() {
    var previousExtraClasses = this.get('previousExtraClasses');
    var extraClasses = this.get('extraClasses');

    // Remove the classes that got removed from `extraClasses`
    previousExtraClasses.forEach(function(className) {
        if (extraClasses.indexOf(className) < 0) {
            this.$().removeClass(className);
        }
    }, this);

    // Add the classes that got added to `extraClasses`
    extraClasses.forEach(function(className) {
        if (previousExtraClasses.indexOf(className) < 0) {
            this.$().addClass(className);
        }
    }, this);

    this.set('previousExtraClasses', extraClasses);
).observesImmediately('extraClasses')

Every time you update extraClasses with a new set of classes, the manageClasses observer will take care of managing the classes on the component. As long as extraClasses returns an array of strings, it can be computed any way you like.

Upvotes: 1

Related Questions