I have some angular 2 components that work fine for a web app.
So, I would want to reuse some of them in an ionic 2 application but without rewriting things.
Ionic has special directives, example: lists. I would have liked to be able to reuse my components by "adding" the ionic directives on top of it.
Ionic syntax:
<ion-list>
<ion-item *ngFor="let product of products">
{{product.name}}
</ion-item>
</ion-list>
Example of angular components:
*Main ionic page:
#Component({
template: `
<ion-header>
<ion-navbar>
<button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>Products</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<product-list [products]="products"></product-list>
</ion-content>
`,
directives: [ProductListComponent],
providers: [ProductService]
})
export class ProductsPage implements OnInit{
products;
constructor(
private navCtrl: NavController,
private productService:ProductService) {
}
ngOnInit() {
this.productService.all().subscribe(data => {
this.products = data;
});
}
}
A list of products:
#Component({
selector: 'product-list',
template: `
<ul>
<li *ngFor="let product of products">
<product-list-element [product]="product"></product-list-element>
</li>
</ul>
`,
directives: [ProductListElementComponent]
})
export class ProductListComponent {
#Input() products;
}
An element of the list
#Component({
selector: 'product-list-element',
template: `
<div>
<h3>{{product.name}}</h3>
</div>
`
})
export class ProductListElementComponent {
#Input() product;
}
Here in the example, there is no much logic so rewriting the template is ok but in the real case...
I don't know how to handle this, I'm new in angular 2.
I think the beginning of an answer will be to hide less things and expose more peace of the template but maybe someone already done this before.
Maybe like so:
<ion-list>
<ion-item *ngFor="let product of products">
<ion-icon name="leaf" item-left></ion-icon>
<product-list-element [product]="product">
<product-title [title]="product.title"></product-title>
</product-list-element>
</ion-item>
</ion-list>
Thank you in advance :)
Related
I'm trying to create a scrollTop button on ionic 3 but it's not working, can someone give me a hint of what I'm doing wrong? How do I proceed to add the scrollTop in the fab ion
This is my code home.ts
import { Component, ViewChild } from '#angular/core';
import { IonicPage, NavController, NavParams, ToastController, Content }
from 'ionic-angular';
import { AngularFireAuth } from "angularfire2/auth";
import { MenuController } from "ionic-angular";
import { PrediosPage } from '../predios/predios';
#IonicPage()
#Component({
selector: 'page-home',
templateUrl: 'home.html',
})
export class HomePage {
#ViewChild('pageTop') pageTop: Content;
public pageScroller(){
this.pageTop.scrollToTop();
}
searchQuery: string = '';
items: any[];
constructor(private afAuth: AngularFireAuth, private toast:
ToastController,
public navCtrl: NavController, public navParams: NavParams, public menu:
MenuController) {
this.initializeItems();
}
And this is my home.html
<ion-content #pageTop>
<div paddign>
<ion-searchbar (ionInput)="getItems($event)" placeholder="Pesquisar">
</ion-searchbar>
<ion-list>
<ion-item *ngFor="let item of items" (click)="itemTapped($event, item)">
<ion-thumbnail item-left>
<img [src]="item.imagem">
</ion-thumbnail>
<h2 style="color:#886AEA">{{ item?.nome }}</h2>
<p>Rua: {{ item?.rua }} - {{ item?.numero }}</p>
</ion-item>
</ion-list>
</div>
<ion-fab right bottom>
<button ion-fab color="darkroyal" (click)="pageTop"><ion-icon name="ios-arrow-up"></ion-icon></button>
</ion-fab>
And this is my home app image
You have to change the following line:
#ViewChild(Content) pageTop: Content;
And, you have to change the click function name on your button on html to that one you have created to make the page scroll to top:
<ion-fab right bottom>
<button ion-fab color="darkroyal" (click)="pageScroller()">
<ion-icon name="ios-arrow-up"></ion-icon></button>
</ion-fab>
I have ionic page that have an image with 100% width and 100% height, I want to change the image source when I click on it.
this is the html source :
<ion-content>
<ion-img class="map" src="img/map.jpg" (click)="changeView()"></ion-img>
<ion-icon class="icon-bonfire" name="ios-bonfire"></ion-icon>
<ion-icon class="icon-heart" name="md-heart"></ion-icon>
<ion-icon class="icon-nuclear" name="md-nuclear"></ion-icon>
<ion-fab top right>
<button ion-fab color="whitecolor"><ion-icon class="calandaricon" name="md-calendar"></ion-icon></button>
</ion-fab>
<ion-fab top left>
<ion-searchbar> </ion-searchbar>
</ion-fab>
<ion-fab bottom right class="fablocate">
<button ion-fab color="whitecolor"><ion-icon class="locateicon" name="md-locate"></ion-icon></button>
</ion-fab>
<ion-fab (click)="ListParrots();" bottom left class="linklist">
<ion-img class="parrot-list-link" src="img/citydirty.jpg"></ion-img>
</ion-fab>
</ion-content>
ts source code is below :
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import {ParrotListPage } from '../parrot-list/parrot-list';
/**
* Generated class for the MapPage page.
*
* See https://ionicframework.com/docs/components/#navigation for more info on
* Ionic pages and navigation.
*/
#IonicPage()
#Component({
selector: 'page-map',
templateUrl: 'map.html',
})
export class MapPage {
images: String[] = Array("img//map.jpg", "img/map1.jpg");
constructor(public navCtrl: NavController, public navParams: NavParams) {
}
changeView(){
}
ionViewDidLoad() {
console.log('ionViewDidLoad MapPage');
}
ListParrots(){
this.navCtrl.push(ParrotListPage);
}
}
can some one help please to complete all the function? thank !
Change your template:
<ion-img class="map" [src]="picToView" (click)="changeView()"></ion-img>
And declare a variable in the class:
picToView:string="img/map.jpg"; // always instatiate with a valid value
And changeView:
changeView(){
this.picToView=.....
}
Regards
Tom
I'm creating an ionic-2 project, where I've a button at the right bottom. My concept is, when I click the button, the time picker should open. I've to select my time and click done.
This is how I've tried:
HTML:
<ion-header>
<ion-navbar color="primary">
<ion-title>Alarms</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-card *ngFor="let alarms of serAlarm">
<ion-card-header>
{{alarms.id}}
<ion-toggle value="foo" checked="true"></ion-toggle>
</ion-card-header>
<ion-card-content>
<ion-checkbox (click)="clickRepeat()"></ion-checkbox> Repeat
<div class="hide">
</div>
</ion-card-content>
<ion-card-content class="top0">
{{alarms.hour}}:{{alarms.minute}}
</ion-card-content>
</ion-card>
<ion-datetime #dateTime displayFormat="HH:mm" pickerFormat="HH:mm" [(ngModel)]="dateTimeModel" (ionChange)="onTimeChange()"></ion-datetime>
<ion-fab right bottom>
<button ion-fab color="primary" (click)="opentime()">
<ion-icon name="add"></ion-icon>
</button>
</ion-fab>
</ion-content>
TS:
import { Component, ViewChild } from '#angular/core';
import { NavController} from 'ionic-angular';
#Component({
selector: 'page-alarm',
templateUrl: 'alarm.html'
})
export class AlarmPage {
time: string = '00:00';
serAlarm = [];
constructor(public navCtrl: NavController) { }
#ViewChild('dateTime') sTime;
opentime(){
this.sTime.open();
}
onTimeChange() {
var res = this.time.toString().split(":");
this.serAlarm.push({
id: "0",
description: "",
hour: res[0],
minute: res[1],
repeat: "0",
action: "0",
active: "1"
});
}
}
Here, everything works fine. But, when I click the + button, I get the error Cannot read the property 'open' of undefined. I guess, the problem is in <ion-datetime> line. But, I can't figure what's wrong. Can someone help me with it? What should I change?
In order to select the element you need to give the correct selector, if you want it to be dateTime then change the element to:
<ion-datetime #dateTime displayFormat="HH:mm" pickerFormat="HH:mm" [(ngModel)]="dateTimeModel" (ionChange)="onTimeChange()"></ion-datetime>
Note that I've changed the ngModel since they had the same name reference.
Now you can get hold of the element with #ViewChild('dateTime') sTime;
I'm using Angular 2 Material sidenav in my project this way:
<md-sidenav-layout>
<md-sidenav #start mode="side" [opened]="true">
<md-nav-list>
</md-nav-list>
</md-sidenav>
<button md-button (click)="start.toggle()">Close</button>
<router-outlet></router-outlet>
</md-sidenav-layout>
How to call start.toggle() from my component instead of element with click event?
Thank you for reading
You want to declare a ViewChild in your controller that references the MdSidenav inside your component, like this:
// Sidemenu
#ViewChild('start') sidenav: MdSidenav;
where start is the name of the component you want to reference, in this case the sidenav.
Next you can call methods on that sidenav, like this.sidenav.toggle() inside your controller's functions.
https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-view-child
Pass the object to your function.
<md-sidenav-layout>
<md-sidenav #start mode="side" [opened]="true">
<md-nav-list>
</md-nav-list>
</md-sidenav>
<button md-button (click)="randomName(start)">Close</button>
<router-outlet></router-outlet>
</md-sidenav-layout>
import {Component} from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html'
})
export class AppComponent {
constructor() {
}
randomName(start: any) {
start.toggle();
}
}
The simplest way for was to pass the drawer to the component that triggers the toggle.
Html:
<mat-drawer #drawer mode="side">
....
</mat-drawer>
<another-component [drawerRef]="drawer"><another-component/>
another-component TS:
export class AnotherComponent implements OnInit {
#Input() drawerRef: MatDrawer;
...
}
another-component HTML:
<button (click)="this.drawerRef.toggle()">
Where another-component is the component that controls the toggle action.
<md-sidenav #sidenav class="example-sidenav" opened="false">
<div class="example-sidenav-content">
<button type="button" md-button (click)="toogleNav(sidenav)">
toogle
</button>
</div>
</md-sidenav>
And in your ts:
export class AppComponent {
toogleNav(nav: any) {
if (nav.opened) {
nav.close()
} else {
nav.open();
}
}
}
I have a page with one list from a JSON file. What I want to do it's to add an order by funcionality. I don't understand yet if I need to use #Pipe or if there is a simpler way.
I'm planning to do it in a modal page.
Thanks in advance any help will be appreciated.
modalpage.html:
<ion-toolbar danger>
<ion-buttons start>
<button (click)="close()">
<ion-icon ios="ios-close" md="md-close"></ion-icon>
</button>
</ion-buttons>
<ion-title text-center>
Ajustes
</ion-title>
<ion-buttons end>
<button (click)="applyFilters()">
<ion-icon ios="ios-checkmark" md="md-checkmark"></ion-icon>
</button>
</ion-buttons>
</ion-toolbar>
<ion-content padding class="rojo">
<h2 text-center>Ordenar resultados por:</h2>
</ion-content>
modalpage.js
import {Page, NavController,ViewController} from 'ionic-angular';
#Page({
templateUrl: 'build/pages/ajustes-listado/ajustes-listado.html',
})
export class AjustesListadoPage {
static get parameters() {
return [[NavController],[ViewController]];
}
constructor(nav, viewController) {
this.nav = nav;
this.viewCtrl = viewController;
}
close(data) {
this.viewCtrl.dismiss(data);
}
applyFilters(){
console.log('aplicando filtros a la lista');
this.close();
}
}
list.html
<ion-navbar *navbar danger>
<ion-title text-center>Listado</ion-title>
<ion-buttons start *ngIf="buscar==false">
<button (click)="search()">
<ion-icon ios="ios-search" md="md-search"></ion-icon>
</button>
</ion-buttons>
<ion-buttons end>
<button (click)="options()">
<ion-icon ios="ios-options" md="md-options"></ion-icon>
</button>
</ion-buttons>
</ion-navbar>
<ion-content class="listado">
<ion-list [virtualScroll]="vets">
<button ion-item text-wrap *virtualItem="let vet" (click)="goToDetails(vet)">
<ion-avatar item-left>
<!-- <ion-img [src]="vet.img || defaultImg"></ion-img> -->
<img src="{{vet.img}}" onError="this.src='./files/gmaps.png';" />
</ion-avatar>
<h2>{{vet.nombre}}</h2>
<p>Direccion: {{vet.direccion}}</p>
</button>
</ion-list>
</ion-content>
list.js
import {DetallesPage} from '../detalles/detalles';
import {OnInit} from '#angular/core';
import {Page, NavController, Platform, NavParams, Modal} from 'ionic-angular';
import {MiServicio} from '../../providers/mi-servicio/mi-servicio';
import {AjustesListadoPage} from '../ajustes-listado/ajustes-listado';
#Page({
templateUrl: 'build/pages/listado/listado.html',
providers:[MiServicio]
})
export class ListadoPage {
static get parameters() {
return [[NavController],[Platform],[MiServicio]];
}
constructor(nav,platform, miServicio) {
this.nav = nav;
this.platform = platform;
this.miServ = miServicio;
this.ngOnInit();
}
ngOnInit() {
this.miServ.getVets().subscribe(
data => this.vets = data
);
}
}
Angular2 doesn't provide the orderBy filter (now "pipe") like angular 1 does.
Angular does not ship with pipes for filtering or sorting lists. Developers familiar with Angular 1 know these as filter and orderBy. There are no equivalents in Angular 2.
refer: https://angular.io/docs/ts/latest/guide/pipes.html#!#no-filter-pipe
You'll need to sort the items in your component. The best option is always sort them on the server-side, but if you know there's only a few items or you really want to sort on the client-side, you can use the array.sort() method.
Examples and documentation:
http://www.w3schools.com/jsref/jsref_sort.asp
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
You said you have the list in a JSON file, so it's a persistent data isn't it?
Take a look at this: Sorting with map
I think this will be the best option for you.