简体   繁体   中英

Split `list` and `item` of the Angular Material grid list component in separate components?

I am using the Angular2 Material grid list component and I want to split the list and the item in separate components.

Here's my list :

@Component({
  selector: 'app-list',
  template: `
    <md-grid-list cols="12">
        <app-item *ngFor="let item of items"></app-item>
    </md-grid-list>
  `
})
export class ListComponent {
  items: Array<number> = [1, 2]; // dummy data
}

Here is my item component:

@Component({
  selector: 'app-item',
  template: `
    <md-grid-tile [colspan]="6">
      First
    </md-grid-tile>
    <md-grid-tile [colspan]="6">
      Second
    </md-grid-tile>
  `
})
export class ItemComponent implements OnInit { }

The issue is that the child item component gets rendered in the actual DOM inside a wrapper <app-item> custom (invalid) DOM element. And the styles are broken because the Angular2 Material grid list component expects the following structure:

<md-grid-list cols="12">
  <!-- Item 1 -->
  <md-grid-tile [colspan]="6"></md-grid-tile>
  <md-grid-tile [colspan]="6"></md-grid-tile>

  <!-- Item 2 -->
  <md-grid-tile [colspan]="6"></md-grid-tile>
  <md-grid-tile [colspan]="6"></md-grid-tile>
</md-grid-list>

... but the actual DOM structure is:

<md-grid-list cols="12">
  <!-- Item 1 -->
  <app-item> <!-- same issue if I replace this with `div` or `span` -->
    <md-grid-tile [colspan]="6"></md-grid-tile>
    <md-grid-tile [colspan]="6"></md-grid-tile>
  </app-item>

  <!-- Item 2 -->
  <app-item>
    <md-grid-tile [colspan]="6"></md-grid-tile>
    <md-grid-tile [colspan]="6"></md-grid-tile>
  </app-item>
</md-grid-list>

I have looked at ng-content , DynamicComponentLoader , the ViewContainerRef , but they don't seem to provide a solution to this as far as I can see.

I read the response here , but the attribute selectors don't work for me as well. It doesn't matter if the wrapping component is <app-item> or <div> or <span> or whatever, the styling always breaks.

Does anybody know if I can render a child component without any parent wrapper? Is there a workaround you can suggest for my use-case?

@sergeras, the solution you proposed doesn't work.

I was very surprised that the approach by using attribute selectors and <ng-container> is causing an error and I raised an issue in the Angular Material 2 official repository.

Jeremy Elbourn, one of the top contributors to the Angular Material 2, provided an explanation :

... you can view the grid-list as a single UI component with a specific API. Placing the grid tiles inside of another component hides them completely from the grid list since each component is effectively a black box.

Therefore, the answer to my question is: It is currently not possible to separate in different Angular 2 components the list and the list item of the Angular2 Material grid list component . And there is no workaround.

You can use attribute selectors and ng-container , which would make your parent component like this:

@Component({
  selector: 'app-list',
  template: `
    <md-grid-list cols="12">
        <ng-container appItem *ngFor="let item of items"></ng-container>
    </md-grid-list>
  `
})

And then the child component would be like this:

@Component({
  selector: '[appItem]',
  template: `
    <md-grid-tile [colspan]="6">
      First
    </md-grid-tile>
    <md-grid-tile [colspan]="6">
      Second
    </md-grid-tile>
  `
})
export class VehiclesItemComponent implements OnInit { }

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