admin管理员组

文章数量:1328401

I am fairly new to Angular and came from React.js background.

I have made a simple grid ponent like below:

gridponent.js

import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-grid',
  template: `
    <div [ngStyle]="styles()" [ngClass]="passClass">
      <ng-content></ng-content>
    </div>
  `,
  styles: [`
    div {
      display: flex;
    }
  `]
})
export class GridComponent implements OnInit {
  @Input() direction: string;
  @Input() justify: string;
  @Input() align: string;
  @Input() width: string;
  @Input() passClass: string;

  constructor() { }

  ngOnInit() {
  }

  styles() {
    return {
      'flex-direction': this.direction || 'row',
      'justify-content': this.justify || 'flex-start',
      'align-items': this.align || 'flex-start',
      ...(this.width && { width: this.width })
    };
  }
}

I am fairly new to Angular and came from React.js background.

I have made a simple grid ponent like below:

grid.ponent.js

import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-grid',
  template: `
    <div [ngStyle]="styles()" [ngClass]="passClass">
      <ng-content></ng-content>
    </div>
  `,
  styles: [`
    div {
      display: flex;
    }
  `]
})
export class GridComponent implements OnInit {
  @Input() direction: string;
  @Input() justify: string;
  @Input() align: string;
  @Input() width: string;
  @Input() passClass: string;

  constructor() { }

  ngOnInit() {
  }

  styles() {
    return {
      'flex-direction': this.direction || 'row',
      'justify-content': this.justify || 'flex-start',
      'align-items': this.align || 'flex-start',
      ...(this.width && { width: this.width })
    };
  }
}

And I want to use it in other ponents like below: aboutus.ponent.html

<app-grid passClass="about-us page-container">
  <app-grid direction="column" passClass="left">
    <div class="title blue bold">
      An open munity For Everyone
    </div>
    <div class="large-desc grey">
      This conference is brought to you by
      the Go Language Community in
      India together with the Emerging
      Technology Trust (ETT). ETT is a non-
      profit organization, established to
      organize and conduct technology
      conferences in India. It’s current
      portfolio includes
    </div>
  </app-grid>
</app-grid>

aboutus.ponent.sass

.about-us
  position: relative
  .left
    width: 50%
    &:after
      bottom: 0
      right: 0
      z-index: 0
      margin-right: -5vw
      position: absolute
      content: url(../../assets/images/footer.svg)

But, what happens is the CSS attached with the second ponent will not work.

I know a little bit about CSS isolation but could not understand if it affects here.

P.S.: Please feel free to provide feedback to things outside of scope this question as well.

Share Improve this question asked Feb 3, 2019 at 15:39 TolseeTolsee 1,70516 silver badges23 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

It is not possible to pass CSS classes as variables in your template. So if your expectation in aboutus.ponent.html was to be able to pass the left CSS class as a variable in your template, that will not work.

There are a few things I can point out that will hopefully help:

  1. If you want to modify a CSS class that is internal to a ponent from outside that ponent, one option is to use ng-deep.

  2. In your particular case, I don't think ng-deep is necessary. I'd suggest to drop the div element within the app-grid ponent and instead apply the styles to the host element using @HostBinding decorator. With that approach you can drop the passCss altogether because now wherever you use yourapp-grid ponent you can style that ponent in CSS using the app-grid selector.

    grid.ponent.ts:

    import { Component, OnInit, Input, HostBinding, SafeStyle } from '@angular/core';
    
    @Component({
      selector: 'app-grid',
      template: `<ng-content></ng-content>`,
      styles: [`
        :host {
          display: flex;
        }
      `]
    })
    export class GridComponent implements OnInit {
      @Input() direction: string;
      @Input() justify: string;
      @Input() align: string;
      @Input() width: string;
    
      constructor(private sanitizer:DomSanitizer) { }
    
      ngOnInit() {
      }
    
      @HostBinding('style')
      styles(): SafeStyle {
        const styles = `
          flex-direction: ${this.direction || 'row'};
          justify-content: ${this.justify || 'flex-start'};
          align-items: ${this.align || 'flex-start'};
       `;
        return this.sanitizer.bypassSecurityTrustStyle(styles);
      }
    }
    

    aboutus.ponent.sass:

      app-grid {
        // You can style the host element of a ponent
        // just like any native HTML element and without
        // needing to use `ng-deep`
      }
    
  3. You may also want to look into CSS Custom Properties. Custom CSS properties are not shielded by view-encapsulation. This gives you the ability to create a CSS API for a ponent, if you will, and those properties can be used anywhere within a ponent.

    aboutus.ponent.sass

    app-grid {
      --image: url(../../assets/images/footer.svg)
    }
    

    grid.ponent.sass

    div {
      content: var(--image);
    }
    

If you want style some element in other ponent use :host and /deep/ modifiers(deprecated - Alternative to /deep/). More about this feature you can read in documentation

In your case this should work:

:host /deep/ {
    .left {
        width: 50%
        &:after {
          bottom: 0
          right: 0
          z-index: 0
          margin-right: -5vw
          position: absolute
          content: url(../../assets/images/footer.svg)
       }
    }
}

You can also disable encapsulation for this ponent:

@Component({
  selector: 'app-grid',
  template: `
    <div [ngStyle]="styles()" [ngClass]="passClass">
      <ng-content></ng-content>
    </div>
  `,
  styles: [`
    div {
      display: flex;
    }
  `],
  encapsulation: ViewEncapsulation.None
})

本文标签: javascriptAngular 7 CSS not working while using reusable componentStack Overflow