[RC0] How to use Ionic components inside custom components/directives


#1

I am trying to use Ionic components in a custom component, but it seems that the styles are not applied.

<ion-col width-90>
...

Before RC0 it seems that it was resolved with:

import {IONIC_DIRECTIVES} from "ionic-angular";
...
@Component({
   directives[IONIC_DIRECTIVES]
   ...

But directives are not supported anymore in components.

Moreover, adding IONIC_DIRECTIVES to app.module.ts declarations generates errors about duplicated declarations. I recall reading somewhere that IONIC_DIRECTIVES are already bootstrapped in the App in RC0, so that must be it.

Then, what I am missing here?


Ionic component styles not applied inside custom components
#2

Starting from a blank Ionic2 project to test this issue and using this code:

<ion-content padding>
  <ion-grid>    
    <ion-row>
      <ion-badge item-right>Renders ok in main page</ion-badge>
    </ion-row>
    <ion-row *ngFor="let item of items">
      <ion-col width-90>
        {{ item.Name }}
      </ion-col>
      <ion-col width-10>
        <ion-icon item-right [name]="item.icon"></ion-icon>        
      </ion-col>
    </ion-row>
    <ion-row>
      <ion-badge item-right color="danger">But not if rendered through a component...</ion-badge>
    </ion-row>
    <ion-row *ngFor="let item of items">
      <custom-component [myItem]="item"></custom-component>
    </ion-row>
  </ion-grid>
</ion-content>

And the component (custom-component.ts):

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

@Component({
  selector: 'custom-component',
  templateUrl: 'custom-component.html'
})
export class CustomComponent {
  item: any;

  @Input() 
  set myItem(myItem: string) {
    this.item = myItem;
    console.log(JSON.stringify(this.item));
  }

  constructor() {  }
}

And (custom-component.html):

  <ion-col width-90>
     {{ item.Name }}
  </ion-col>
  <ion-col width-10>
    <ion-icon item-right [name]="item.icon"></ion-icon>        
  </ion-col>

This is the result:

Should I import something in my component to be able to use the Ionic classes (like IONIC_DIRECTIVES in previous beta)?


#3

In docs: http://ionicframework.com/docs/v2/api/IONIC_DIRECTIVES/

_“The core Ionic directives are automatically available when you bootstrap your app with the IonicModule. This means if you are using custom components you do not need to import IONIC_DIRECTIVES as they are part of the app’s default directives.”

So… shouldn’t be necessary import IONIC_DIRECTIVES;


#4

Yes @mauricionarcizo, that’s what I thought, but somehow it does not work as expected. Maybe it is a bug, but I would expect more people complaining about it, if it really was one. The more simple explanation is that I am missing something…

Thanks for looking into it.


#5

This might be a CSS related issue.

Normally the resulting HTML looks (roughly) like this:

<ion-row>
  <ion-col width-90>
    ...
  </ion-col>
  <ion-col width-10>
    ...
  </ion-col>
</ion-row>

But you are using the following code:

<ion-row *ngFor="let item of items">
  <custom-component [myItem]="item"></custom-component>
</ion-row>

This will generate HTML that looks like that:

<ion-row>
  <custom-component>
    <ion-col width-90>
      ...
    </ion-col>
    <ion-col width-10>
      ...
    </ion-col>
  </custom-component>
</ion-row>

In the first example the order is ion-row > ion-col in the second example the order is ion-row > custom-component > ion-col. The custom element in between might break some things. For example CSS selectors or the available width.


If you are able to, try to use the following code. Maybe it works: :slight_smile:

page.html

<custom-component *ngFor="let item of items" [myItem]="item"></custom-component>

custom-component.html

<ion-row>
  <ion-col width-90>
     {{ item.Name }}
  </ion-col>
  <ion-col width-10>
    <ion-icon item-right [name]="item.icon"></ion-icon>        
  </ion-col>
</ion-row>

Style gone if using ionic ui components inside the custom component
#6

Yes! That was it !

I can’t iterate over my custom-component, because in the real app there are several custom types which are rendered conditionally in the ngFor. But introducing a simple div does the trick:

<ion-content padding>
  <ion-grid>	
    <ion-row>
      <ion-badge item-right>Renders ok in main page</ion-badge>
    </ion-row>
    <div *ngFor="let item of items">
      <ion-row>
        <ion-col width-90>
          {{ item.Name }}
        </ion-col>
        <ion-col width-10>
          <ion-icon item-right [name]="item.icon"></ion-icon>        
        </ion-col>
      </ion-row>
    </div>
    <ion-row>
      <ion-badge item-right color="danger">But not if rendered through a component...</ion-badge>
    </ion-row>
    <div *ngFor="let item of items">
      <custom-component [myItem]="item"></custom-component>
    </div>
  </ion-grid>
</ion-content>

And the custom-component.html:

<ion-row>
  <ion-col width-90>
     {{ item.Name }}
  </ion-col>
  <ion-col width-10>
    <ion-icon item-right [name]="item.icon"></ion-icon>        
  </ion-col>
</ion-row>

Gives the desired result:

Thanks for your help @alex_pl.


#7

ahh… angular1 had ‘replace: true’ option in the directives, but seems angular (2/4/5) doesn’t. that’s sad.