Flex-layout: Responsive ngClass (ngClass.xs...ngClass.xl) removing class applied by normal ngClass

Created on 24 Jun 2019  路  6Comments  路  Source: angular/flex-layout

Bug Report

When we have Responsive ngClass and normal ngClass responsive ngClass removed class applied by normal ngClass

Example:

<div ngClass="box" ngClass.xs="extra-small-device" ngClass.sm="small-device" ngClass.md="medium-device" ngClass.lg="large-device"
 ngClass.xl="extra-large-device">
    test
</div>

What is the expected behavior?

For above code that div should always have class "box". Also based on screen size that responsive class also should get added

What is the current behavior?

Only responsive class get added that default class "box" got removed

What are the steps to reproduce?

https://stackblitz.com/edit/angular-eqf3ac?file=src%2Fapp%2Fapp.component.html

What is the use-case or motivation for changing an existing behavior?

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

{
    "@angular/cdk": "^8.0.0-rc.0",
    "@angular/common": "^8.0.0",
    "@angular/compiler": "^8.0.0",
    "@angular/core": "^8.0.0",
    "@angular/flex-layout": "^8.0.0-beta.26",
    "@angular/forms": "^8.0.0",
    "@angular/platform-browser": "^8.0.0",
    "@angular/platform-browser-dynamic": "^8.0.0",
    "@angular/router": "^8.0.0",
    "core-js": "2",
    "rxjs": "^6.5.2",
    "zone.js": "^0.9.1"
  }

Is there anything else we should know?

discussion

All 6 comments

This is actually how the API was originally designed, which precedes me believe it or not. I'll discuss this with @ThomasBurleson, but any departure from this would be a breaking change for those relying on this behavior.

If you'd like, you could create a custom implementation of the NgClass directive, substituting the constructor for the following code:

super(elementRef, null!, styler, marshal);
if (!this.ngClassInstance) {
  // Create an instance NgClass Directive instance only if `ngClass=""` has NOT been defined on
  // the same host element; since the responsive variations may be defined...
  this.ngClassInstance = new NgClass(this.delegate);
  this.setValue('', '');
} else {
  this.setValue(this.ngClassInstance.klass, '');
}
this.init();

@CaerusKaru But the documentation says as below (https://github.com/angular/flex-layout/wiki/ngClass-API#standard-class-features)

the default classes (specified by class="" and ngClass="..." will be preserved (and merged) into other activation class lists UNLESS the breakpoint has specified that a default class should be removed.

update from 7 to 8, now

      <div
        ngClass.xs="__top-content--xs"
        ngClass.sm="__top-content--sm"
        class="__top_content">

__top_content class is removed completely

Just stumbled across the same issue. I would expect the ngClass directive to be applied all the time. As @ravinsinghd figured out this behaviour is also described in the documentation.

However, the class directive did work for me and is not overwritten by the responsive ngClass and I can use this as workaround.

Does not work (but I would expect test to be applied except it is overwritten in the ngClass.lt-md):
<div [ngClass]="{ 'test': true }" [ngClass.lt-md]="{ 'bla': true }"

Does work for me:
<div [class.test]="true" [ngClass.lt-md]="{ 'bla': true }"

The workaround gets kind of messy and hard to read if you want to apply multiple classes with the regular ngClass.

Duplicate of #832

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Kizmar picture Kizmar  路  4Comments

manuelbachl picture manuelbachl  路  5Comments

mackelito picture mackelito  路  3Comments

mhosman picture mhosman  路  3Comments

Pikachews picture Pikachews  路  4Comments