How to make a directive or equivalent?


#1

Hi, i was trying to see angular 2 docs but seems to me that the server is down, how does it works the directives in ionic 2? should i use the component decorator or is there a directive decorator? how do i use it inside a page?


#2

Use the @Directive annotation explained here.

In practice it will look something like this example (taken from here)

import {directive, Component, ElementRef, Renderer} from 'angular2/'core;
@Directive({
    selector: '[x-large]' // using [ ] means selecting attributes
})

export class XLarge {
constructor(element: ElementRef, renderer: Renderer) {
    // simple DOM manipulation to set font size to x-large
    // `nativeElement` is the direct reference to the DOM element
    // element.nativeElement.style.fontSize = 'x-large';

    // for server/webworker support use the renderer
    renderer.setElementStyle(element, 'fontSize', 'x-large');
  }
}

#3

Hi, thanks for answering, the first link goes nowhere, probably server is down, what about a directive with a template, like a component inside a page?


#4

Use a component. Components can utilize as small a space as they require.

I’m using one similar to this:

import {Component, Input} from "angular2/core";
import {NavController} from "ionic-framework/ionic";
import {ArticleFeatureModel} from "../../models/ArticleFeatureModel";
import {ArticlePage} from "../../article/page/ArticlePage";
import {NavParams} from "ionic-framework/ionic";

@Component({
    templateUrl: "app/article-list/feature/ArticleFeature.html",
    selector: "article-feature,"
})
export class ArticleFeature {
    @Input() private model: ArticleFeatureModel;

    private nav: NavController;

    constructor(nav: NavController) {
        this.nav = nav;
        this.model = this.model || new ArticleFeatureModel();
}

#5

What about using it in the page?, i suppose i have to import it in the page and put it in the providers or something array in the decorator options?


#6

That’s how the one I mentioned is being used

From another component’s template referencing the previously posted component:

<article-feature
    [model] = feature>
</article-feature>

<article-preview
   *ngFor="#item of items"
    [model] = item >
</article-preview>

#7

So as far as i remember the [providers] array in the @page decorator is for services, is it also for components or they area supposed to go in another array?


#8

it goes in ‘directives’

@Component({
    selector: "article-list",
    templateUrl: "app/article-list/list/ArticleList.html",
    directives: [ArticlePreview, ArticleFeature]
})

#9

Cool, thanks, sorry for the bother but with the angular docs server down i’m in the dark here.


#10

(I didn’t research this or test it; just winging it but it’ll put you in the right direction)

You can create a directive like so:

import {Directive} from 'angular2/core';

@Directive({
  selector: 'foo',
  template: './foo.html'
)}
export class FooDirective { }

And add it to your page like so:

import {FooDirective} from './foo'

@Page({
  templateUrl: '../page.html',
  directives: [FooDirective],
})

and show it in your html like so:
<foo></foo>

Components are also an option and are a superset of Directives. A good rule of thumb is to use Directives when you only want only one element and Components when you want to create whole sections of HTML.


#11

Thanks, already got this working a couple of days ago.


#12

Glad to hear it! Maybe someone will find this through google. :slight_smile:


#13

I’ve followed some of the code from the above replies to create a component. The component is being inserted into the page but the problem is that ion specific directives aren’t loaded.

home.html:

<ion-content padding>

  <advanced-card></advanced-card>

  <!-- Contents below are identical to whats in advanced-card -->
  <ion-card>
    <ion-item>
      <h1>header 1</h1>
      <p>paragraph 1</p>
    </ion-item>
  </ion-card>

</ion-content>

home.ts

import {Page, NavController} from 'ionic-framework/ionic';
import {AdvancedCard} from '../advanced-card/advanced-card';

@Page({
  templateUrl: 'build/pages/home/home.html',
  directives: [AdvancedCard]
})
export class HomePage {
  constructor(nav: NavController) {
    this.nav = nav;
  }
}

advanced-card.html:

<ion-card>
  <ion-item>
    <h1>header 1</h1>
    <p>paragraph 1</p>
  </ion-item>
</ion-card>

advanced-card.ts:

import {Component} from 'angular2/core';

@Component({
  selector: 'advanced-card',
  templateUrl: 'build/pages/advanced-card/advanced-card.html'
})
export class AdvancedCard {
  constructor(){
  }
}

So home.html is showing the same ion-card twice - once from a component (advanced-card) and the second time the html is directly in home.html. But the ion-card thats inside advanced-card does not load any ion directives. For example the ion-item should have a class called item but that doesn’t exist in the ion-item thats in advanced card.

How can my custom component load in and render ion directives?

Thanks


Custom Components and Ionic Styles
#14

Nope, @Page comes with the IONIC_DIRECTIVES by default, if you’re using the @Component you need to include them in the directives array:

import {Component} from 'angular2/core';
import {IONIC_DIRECTIVES} from 'ionic/ionic';
@Component({
  selector: 'advanced-card',
  templateUrl: 'build/pages/advanced-card/advanced-card.html'
  directives: [IONIC_DIRECTIVES]
})
.....

When creating one use the generators, they had this already done, that’s why i know about it.


Styling is not applied to buttons in components
#15

Thanks so much, that was it! Although I had to change the import to:
import {IONIC_DIRECTIVES} from 'ionic-framework/ionic';

When creating one use the generators, they had this already done, that’s why i know about it.

I should’ve noticed that since I was playing with generators but this one component I was having issues with I created manually.


#16

Why did you have to change the import to that, is your webpack miss-configured?


#17

@cbautista1002 in your example, how can I add an input to pass the header (h1) element for example? Something like this:

<advanced-card myheader='Test'></advanced-card>

asd

<ion-card>
  <ion-item>
    <h1>{{myheader}}</h1>
    <p>paragraph 1</p>
  </ion-item>
</ion-card>

Thanks in advance


#18

It should be something like this

@Component({
    templateUrl: "path/to/AdvancedCard.html",
    selector: "advanced-card"
})
export class ArticlePage {
    @Input() protected myHeader: string;
    ...
}

#19

@swarner I’m getting an error at the @Input() protected… statement and the component won’t load. What am I missing?

import {Component, Input} from 'angular2/core';
import {IONIC_DIRECTIVES} from 'ionic-framework/ionic';

@Component({
  selector: 'advanced-card',
  templateUrl: 'build/pages/advanced-card/advanced-card.html',
  directives: [IONIC_DIRECTIVES]
})
export class AdvancedCard {
  @Input() protected myHeader: string; 
  constructor(){
  }
}

#20

Post your error for context.