简体   繁体   中英

Angular2 components style driven by container defined CSS

Let's say I have a component MyComponent whose view contains a table

        <table>
            <thead>
                <tr>
                    <th class="col1">COL1</th>
                    <th class="col2">COL2</th>
                    <th class="col3">COL3</th>
                </tr>
            </thead>
            <tbody>
                <tr *ngFor="#item of items">
                    <td class="col1">{{item.content1}}</td>
                    <td class="col2">{{item.content2}}</td>
                    <td class="col3">{{item.content3}}</td>
                </tr>
            </tbody>
        </table>

I would like to MyComponent within different container (eg Container1 and Container2 ) and be able to define some attributes of the table (eg the width of each column) using the CSS files I can attach to the containers. For instance in Container1 I could define a CSS file like this

.col1 {
    width: 40%;
}
.col2 {
    width: 30%;
}
.col3 {
    width: 30%;
}

while in Container2 I could have a different CSS file with different attributes. Is this possible? Thanks

You could leverage ngStyle and Input for example:

MyComponent would be:

@Component({
  selector:'table-component',
  template:`
    <table>
      <thead>
        <tr>
          <th [ngStyle]="col1css">COL1</th>
          <th [ngStyle]="col2css">COL2</th>
          <th [ngStyle]="col3css">COL3</th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="#item of items">
          <td [ngStyle]="col1css">{{item.content1}}</td>
          <td [ngStyle]="col2css">{{item.content2}}</td>
          <td [ngStyle]="col3css">{{item.content3}}</td>
        </tr>
      </tbody>
  </table>`
})
export class MyComponent{
  @Input() col1Css;
  @Input() col2Css;
  @Input() col3Css;
}

And then in the containers:

@Component({
    selector: 'container1',
    directives:[MyComponent],
    template: `<table-component [col2Css]="col2Css" [col3Css]="col3Css" [col1Css]="col1Css"></table-component>`
})
export class Container1 {
  col1Css = {'width':'40%'};
  col2Css = {'width':'30%'};
  col3Css = {'width':'30%'};
}

Example in a plunker

If you have different .css files, you could leverage styleUrls in @Component decorator which can accept array of string. Please note that you can achieve your goal many ways and it has a broad scope so its hard to say particular way. But I feel like this can help you (don't know up to which extend). In plunker I'm using different stylesheets with different attributes as you said. Your question can have many answers.

http://plnkr.co/edit/RaJgtc?p=preview

@Component({
  ...
  styleUrls: ['src/style.css','src/styleone.css'],
  ...
})

I suggest to first go with @Abdulrahman's approach and if you run into situations where you need more flexibility because you don't know in advance what should be able to be styled from the outside, you can use shadow-piercing CSS combinator >>> :

@Component({
  selector: 'container1-cmp',
  directives: [MyComponent],
  template: `
    <my-component></my-component>
    <my-component></my-component>
    <my-component></my-component>`,
  styles: [`
    my-component >>> .col1 { width: 40%; }
    my-component >>> .col2 { width: 30%; }
    my-component >>> .col3 { width: 30%; }
  `]
})
export class Container1Cmp {
}
@Component({
  selector: 'container2-cmp',
  directives: [MyComponent],
  template: `
    <my-component></my-component>
    <my-component></my-component>
    <my-component></my-component>`,
  styles: [`
    my-component >>> .col1 { width: 10%; }
    my-component >>> .col2 { width: 10%; }
    my-component >>> .col3 { width: 50%; }
  `]
})
export class Container2Cmp {
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM