how to get the parent node data from a detail grid - ag-grid

I am creating a checkbox component in a detail grid which needs to be disabled if a column value in the parent node is false.
import { Component, OnDestroy } from '#angular/core';
import { ICellRendererAngularComp } from '#ag-grid-community/angular-legacy';
import { ICellRendererParams } from '#ag-grid-community/core';
#Component({
// tslint:disable-next-line: component-selector
selector: 'checkboxRenderer',
template: `
<input
type="checkbox"
(click)="checkedHandler($event)"
[disabled]="!params.column.isCellEditable(params.node)"
[checked]="params.value"
/>
`,
})
export class CheckboxRenderer implements ICellRendererAngularComp, OnDestroy {
params: ICellRendererParams ;
isEditable: boolean = false;
needRefresh = true;
agInit(params: ICellRendererParams): void {
this.params = params;
}
checkedHandler(event: MouseEvent): void {
const checked = (<HTMLInputElement>event.target).checked;
const colId = this.params.column.getColId();
const isEditable = this.params.column.isCellEditable(this.params.node);
if (isEditable) {
this.params.node.setDataValue(colId, checked);
this.needRefresh = true;
}
}
refresh(_params: any): boolean {
const r = this.needRefresh;
this.needRefresh = false;
return r;
}
ngOnDestroy(): void {}
}
in my detailGridOptions I created a columnTypes 'billing' and created a function to define if the field is editable
detailGridOptions: {
columnTypes: {
billing: {
editable: (params: EditableCallbackParams) => {
const invoice = params.node.parent.data;
/*** the params.node.parent doesn't have a data ***/
return !invoice.approved;
},
}
},
frameworkComponents: {
checkbox: CheckboxRenderer,
currency: CurrencyComponent,
},
columnDefs: [
{ field: 'name', headerName: 'Name' },
{ field: 'billable', headerName: 'Billable', type: 'billing', cellRenderer: 'checkbox', onCellValueChanged: this.onToggleDetailBillable.bind(this), },
]
}
My question how do I retrieve the parent node data from the detailGridOptions. I am using those packages since I am still running angular 8.2.2
"#ag-grid-community/angular-legacy": "^28.1.1",
"#ag-grid-community/client-side-row-model": "^27.3.0",
"#ag-grid-community/core": "^27.3.0",
"#ag-grid-community/infinite-row-model": "^27.3.0",
"#ag-grid-enterprise/core": "^27.3.0",
"#ag-grid-enterprise/master-detail": "^27.3.0",
"#ag-grid-enterprise/menu": "^27.3.0",
"#ag-grid-enterprise/row-grouping": "^27.3.0",
"#ag-grid-enterprise/status-bar": "^27.3.0",
Thanks
Pascal

Related

How to properly define a CodeMirror language?

I'm trying to provide a basic autocompletion for something like this:
db.collection("Items").where("name", "==", "temp").limit(1).get();
Here's the code I have so far, using StreamLanguage of CodeMirror 6:
import {
IndentContext,
LanguageSupport,
StreamLanguage,
StringStream
} from "#codemirror/language";
import { tags as t } from "#lezer/highlight";
export const FireStoreLanguage = StreamLanguage.define({
name: "firestore",
startState: (indentUnit: number) => {
return {};
},
token: (stream: StringStream, state: any = {}): string | null => {
console.log(stream);
if (stream.match("db")) {
state.db = true;
return "keyword";
}
if (stream.match(".")) {
if (state.db) {
state.db = false;
state.collection = true;
return "keyword";
} else if (state.collection) {
state.collection = false;
state.where = true;
return "keyword";
} else if (state.where) {
state.where = false;
state.limit = true;
return "keyword";
} else if (state.limit) {
state.limit = false;
return "keyword";
}
}
if (stream.match("collection")) {
if (state.db) {
state.collection = true;
return "keyword";
}
}
if (stream.match("where")) {
if (state.collection) {
state.where = true;
return "keyword";
}
}
if (stream.match("limit")) {
if (state.where) {
state.limit = true;
return "keyword";
}
}
if (stream.match("get")) {
if (state.limit) {
state.limit = false;
return "keyword";
}
}
if (stream.match(/"(?:[^\\"]|\\.)*"/)) {
if (state.collection) {
return "string";
}
if (state.where) {
state.where = false;
state.whereValue = true;
return "string";
}
if (state.whereValue) {
state.whereValue = false;
return "string";
}
if (stream.match("==")) {
if (state.whereValue) {
state.whereValue = false;
state.whereOperator = true;
return "operator";
}
}
if (stream.match(/[0-9]+/)) {
if (state.limit) {
return "number";
}
}
}
stream.next();
return null;
},
blankLine: (state: {}, indentUnit: number): void => {},
copyState: (state: {}) => {},
indent: (
state: {},
textAfter: string,
context: IndentContext
): number | null => {
return 1;
},
languageData: {
commentTokens: { line: ";" },
},
tokenTable: {
db: t.keyword,
dot: t.punctuation,
collection: t.keyword,
get: t.keyword,
lParen: t.punctuation,
rParen: t.punctuation,
string: t.string,
},
});
export function firestore() {
return new LanguageSupport(FireStoreLanguage);
}
In React, here's how I use it(after building it):
import CodeMirror from "#uiw/react-codemirror";
import React from "react";
import { firestore } from "./firestore";
function App() {
const onChange = React.useCallback((value, viewUpdate) => {
console.log("value:", value);
}, []);
return (
<CodeMirror
value={``}
height="100vh"
extensions={[firestore()]}
onChange={onChange}
/>
);
}
export default App;
The editor loads okay, but no autocompletion is provided while I type!
What am I doing wrong or missing in the code above?
I was missing these parts:
export const FireStoreCompletion = FireStoreLanguage.data.of({
autocomplete: completeFromList([
{ label: "db", type: "namespace" },
{ label: "collection", type: "function" },
{ label: "where", type: "function" },
{ label: "limit", type: "function" },
{ label: "get", type: "function" },
]),
});
export function firestore() {
return new LanguageSupport(FireStoreLanguage, [FireStoreCompletion]);
}

Navigate to specific tab in Ionic 3

I'm having trouble selecting the index of Tabs when on Button click. I'm calling the index like so, in android-tutorial.ts but it isn't working.
I am calling the function in android-tutorial.ts, with the function startApp();
Is there any other way to do this? What am I doing wrong?
Hope you can help me!
tabs-page.ts
mySelectedIndex: number = 0;
tabs: Tab[] = [
{
page: "NoveltiesPage",
icon: "icon-novelties"
},
{
page: "BrandsPage",
icon: "icon-menus"
},
{
page: "LoginPage",
icon: "icon-user"
},
{
page: "StoresPage",
icon: "icon-stores"
},
{
page: "AboutPage",
icon: "custom-hat"
}
];
constructor(public navCtrl: NavController, public events: Events, public alertCtrl: AlertController, public storageProvider: StorageProvider, public pushProvider: PushProvider, public aboutProvider: AboutProvider, private appVersion: AppVersion, public platform: Platform, public deviceProvider: DeviceProvider, public alertProvider: AlertProvider) {
this.platform.ready().then(() => {
this.getVersion();
//Navigate to Login Page on Startup
this.storageProvider.getUser().then((user: User) => {
if (user && user.token) {
let token = user.token;
this.events.publish("user:login", token);
this.pushProvider.start();
}
});
});
this.platform.resume.subscribe(() => {
this.getVersion();
});
this.events.subscribe("user:login", () => {
this.tabs[2].page = "AccountPage";
});
this.events.subscribe("user:logout", () => {
this.tabs[2].page = "LoginPage";
});
this.events.subscribe("user:notification", (data: any) => {
switch (data.additionalData.type) {
case "novelty":
this.events.publish("novelty:new");
this.navCtrl.push("NoveltyPage", {
id: data.additionalData.id
});
break;
// case "message":
// this.events.publish('message:new');
// this.navCtrl.push('MessagePage', {
// id: data.additionalData.id,
// });
// break;
default:
this.events.publish("card:update");
this.alertProvider.show(data.title, data.message);
break;
}
});
}
getVersion() {
//get the version of the method
this.aboutProvider.app().subscribe((data: any) => {
this.curVersion = data.data;
//get platform of the Device
let platform = this.deviceProvider.getPlatform();
let curV: string = this.curVersion.ios;
let store: string = this.curVersion.app_ios_url;
if (platform == "Android") {
curV = this.curVersion.android;
store = this.curVersion.app_android_url;
}
//get the version of the app
this.appVersion
.getVersionNumber()
.then((data: any) => {
let version = data;
if (curV > version) {
switch (this.curVersion.status) {
case "1":
this.alertProvider.action(this.curVersion.title, this.curVersion.message, [{ text: "Cancelar" }, { text: "Atualizar", action: "link", link: store }]);
break;
case "2":
this.alertProvider.action(this.curVersion.title, this.curVersion.message, [{ text: "Atualizar", action: "link", link: store }], false);
break;
default:
break;
}
}
})
.catch(e => {});
});
}
}
android-tutorial.ts
import { Component, ViewChild } from '#angular/core';
import { Storage } from '#ionic/storage';
import { IonicPage, Slides, NavController, Events, NavParams } from 'ionic-angular';
#IonicPage()
#Component({
selector: 'page-android-tutorial',
templateUrl: 'android-tutorial.html',
})
export class AndroidTutorialPage {
seen: boolean;
currentIndex: number = 1;
#ViewChild('slides') slides: Slides;
constructor(public navCtrl: NavController, public navParams: NavParams, public storage: Storage, public events: Events) {
this.seen = this.navParams.data.seen;
if (!this.seen) {
this.seen = false;
}
}
startApp() {
this.navCtrl.setRoot('TabsPage', {
mySelectedIndex : 2
});
this.storage.set('hasSeenTutorial', 'true');
}
back() {
this.navCtrl.pop();
}
slideChanged() {
let index = this.slides.getActiveIndex();
if(index != 4) {
this.currentIndex = this.slides.getActiveIndex() + 1;
}
}
}
tabs-page.html
<ion-tabs [selectedIndex]="mySelectedIndex">
<ion-tab [root]="tab.page" tabIcon="{{tab.icon}}" *ngFor="let tab of tabs"></ion-tab>
</ion-tabs>
Ok I find a way to do it.
Here's how i solved it. I needed to be able to pass an Index to the tabs-page.ts from android-tutorial.ts
Here's the only thing I added:
constructor(public navCtrl: NavController, public events: Events, public alertCtrl: AlertController, public storageProvider: StorageProvider, public pushProvider: PushProvider, public aboutProvider: AboutProvider, private appVersion: AppVersion, public platform: Platform, public deviceProvider: DeviceProvider, public alertProvider: AlertProvider, public params: NavParams) {
this.mySelectedIndex = this.params.get('mySelectedIndex'); <---- THIS IS THE LINE I ADDED
this.platform.ready().then(() => {
this.getVersion();
//Navigate to Login Page on Startup
this.storageProvider.getUser().then((user: User) => {
if (user && user.token) {
let token = user.token;
this.events.publish("user:login", token);
this.pushProvider.start();
}
});
});
this.platform.resume.subscribe(() => {
this.getVersion();
});
this.events.subscribe("user:login", () => {
this.tabs[2].page = "AccountPage";
});
this.events.subscribe("user:logout", () => {
this.tabs[2].page = "LoginPage";
});
this.events.subscribe("user:notification", (data: any) => {
switch (data.additionalData.type) {
case "novelty":
this.events.publish("novelty:new");
this.navCtrl.push("NoveltyPage", {
id: data.additionalData.id
});
break;
// case "message":
// this.events.publish('message:new');
// this.navCtrl.push('MessagePage', {
// id: data.additionalData.id,
// });
// break;
default:
this.events.publish("card:update");
this.alertProvider.show(data.title, data.message);
break;
}
});
}

Loader Appearing continue in ionic ios when login

I am new to ionic development and I am facing some issue
We are consuming an API in the ionic3 app.
When the user enters the credentials for login whether they are valid or invalid it shows the message according to the results from API in android.
But When i enter the wrong credentials in the ios build it will continue shows the loader and not giving the API result.
Following the app.component
import { Component, ViewChild } from '#angular/core';
import { Platform, Events, Nav, AlertController } from 'ionic-angular';
//import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { MenuController } from 'ionic-angular/components/app/menu-controller';
import { StorageService } from '../pages/shared/storage.service';
import { ToastService } from '../pages/shared/toast.service';
import { Network } from '#ionic-native/network';
//import { Observable } from 'rxjs/Observable';
import { UserService } from '../pages/shared/user.service';
import { Push, PushObject, PushOptions } from '#ionic-native/push';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
#ViewChild(Nav) nav;
alert: any;
isAlertShown: boolean;
task: any;
rootPage: any = '';
userDetails: any;
showSubmenu: boolean = true; //for open always
constructor(public platform: Platform, public splashScreen: SplashScreen,
public menu: MenuController,
private storage: StorageService, private toast: ToastService, public events: Events,
private push: Push,
private alertCtrl: AlertController, public network: Network, private api: UserService) {
platform.ready().then(() => {
this.userDetails = this.storage.getData('userDetails');
this.isAlertShown = false;
this.task = setInterval(() => {
this.checkInternet();
}, 3000);
this.pushSetup();
if (this.userDetails != undefined || this.userDetails != null) {
this.rootPage = 'welcome';
} else {
this.rootPage = 'login';
}
this.initializeApp();
});
events.subscribe('user:login', (username) => {
// user and time are the same arguments passed in `events.publish(user, time)`
this.getLoggedIn();
});
events.subscribe('user:logout', () => {
this.rootPage = 'login';
});
events.subscribe('root:change', (page) => {
// user and time are the same arguments passed in `events.publish(user, time)`
this.rootPage = page;
});
events.subscribe('user:pic', (userpic) => {
// user and time are the same arguments passed in `events.publish(user, time)`
this.userDetails = this.storage.getData('userDetails');
this.userDetails = {
userId: this.userDetails.userId,
username: this.userDetails.username,
profileUrl: userpic
}
this.storage.saveData('userDetails', this.userDetails);
this.getLoggedPic('pic');
});
}
initializeApp() { //for reduce time of white screen after splash
this.platform.ready().then(() => {
// do whatever you need to do here.
setTimeout(() => {
this.splashScreen.hide();
}, 100);
});
}
checkInternet() {
this.alert = this.alertCtrl.create({
title: 'Disconnected',
message: 'Please connect your device to internet',
buttons: [
{
text: 'Try again',
handler: () => {
this.checkagain();
}
}
], enableBackdropDismiss: false
});
this.api.getCategoryList()
.then(result => {
// console.clear();
if (result.type == 'error') {
if (this.isAlertShown == false) {
this.alert.present();
this.isAlertShown = true;
}
this.storage.saveData('connect', 'offline');
}
else if (result.status == true) {
this.storage.saveData('connect', 'online');
this.alert.dismiss();
}
})
}
public checkagain() {
this.isAlertShown = false;
//this.alert.dismiss();
}
public logout(): void {
this.storage.removeData('userDetails');
this.toast.ShowNotification('Logout Successful', 'bottom');
this.rootPage = 'login';
}
getLoggedPic(page) {
this.userDetails = this.storage.getData('userDetails');
if (page == "pic") {
this.userDetails.profileUrl = this.userDetails.profileUrl + "?" + new Date().getTime();
}
}
getLoggedIn() {
this.userDetails = this.storage.getData('userDetails');
if (this.userDetails != undefined || this.userDetails != null) {
this.rootPage = 'welcome';
this.userDetails = this.storage.getData('userDetails');
this.userDetails.profileUrl = this.userDetails.profileUrl + "?" + new Date().getTime();
} else {
this.rootPage = 'login';
}
}
openMenu(): void {
//Commented for click on edit profile to not collepes
//this.showSubmenu = !this.showSubmenu;
}
openPage(pagename: string) {
this.rootPage = pagename;
//this.nav.push(pagename);
}
openHomePage(pagename: string) {
this.rootPage = pagename;
}
pushSetup() {
console.log("inside pushSetup");
const options: PushOptions = {
android: {
senderID: 'xxxxxxxxxxx
forceShow: 'true'
},
ios: {
alert: 'true',
badge: true,
sound: 'false'
}
};
const pushObject: PushObject = this.push.init(options);
pushObject.on('notification').subscribe((notification: any) => console.log('Received a notification', notification));
pushObject.on('registration').subscribe((registration: any) => this.storage.saveData("token", registration.registrationId));
pushObject.on('error').subscribe(error => console.error('Error with Push plugin', error));
}
}
Following is my login.ts
import { Component } from '#angular/core';
import { IonicPage, NavController, Events, LoadingController } from 'ionic-angular';
import { FormGroup, FormBuilder, Validators } from '#angular/forms';
import { UserLogin } from '../shared/user';
import { UserService } from '../shared/user.service';
import { ToastService } from '../shared/toast.service';
import { StorageService } from '../shared/storage.service';
import { MenuController } from 'ionic-angular/components/app/menu-controller';
import { Platform } from 'ionic-angular';
#IonicPage({
name: 'login'
})
#Component({
selector: 'page-login',
templateUrl: 'login.html',
})
export class LoginPage {
public loginForm: FormGroup;
public submitted: boolean = false;
public userDetails: any;
private isUserLoggin: boolean = false;
private devicetype: any;
unamePattern = "(?:\d{10}|\w+#\w+\.\w{2,3})";
constructor(public nav: NavController, public formBuilder: FormBuilder,public platform: Platform,
private userService: UserService, private toast: ToastService, public loading: LoadingController, private storage: StorageService, private menuCtrl: MenuController,
public events: Events) {
if (this.platform.is('ios')) {
this.devicetype = "ios";
}
else {
this.devicetype = "android";
}
this.menuCtrl.enable(false); // for sidemenu disable
this.nav = nav;
this.isUserLoggin = this.userService.isUserLoggedIn();
this.loginForm = formBuilder.group({
username: ['', Validators.compose([Validators.required])],
password: ['', Validators.compose([Validators.required])]
});
}
// get username() {
// return this.loginForm.get('username');
// }
public save(model: UserLogin, isValid: boolean) {
this.submitted = true;
if (isValid) {
const formData = new FormData();
debugger
formData.append("user_login", model.username);
formData.append("user_password", model.password);
formData.append("device_type",this.devicetype);
formData.append("device_id",""+this.storage.getData("token"));
// console.log("storage id of device ="+this.storage.getData("token"));
let loader = this.loading.create({
content: 'Please wait'
});
loader.present().then(() => {
});
//this.toast.ShowLoaderOnLoad();
try {
this.userService.loginUser(formData)
.then(result => {
loader.dismiss();
if (result.status === true) {
this.userDetails = {
userId: result.data.user_id,
username: result.data.first_name,
profileUrl: result.data.picture_url
}
this.storage.saveData('userDetails', this.userDetails);
this.events.publish('user:login', result.data.first_name); //send an event to menu for show name
this.toast.ShowNotification(result.message, 'bottom');
this.nav.setRoot('welcome');
}
else if (result.status === false) {
this.loginForm = this.formBuilder.group({
username: [model.username, Validators.compose([Validators.required])],
password: ['', Validators.compose([Validators.required])]
});
this.submitted = false;
this.toast.ShowNotification(result.message, 'bottom');
}
else {
this.toast.ShowNotification('Something went wrong!', 'bottom');
this.loginForm.reset();
this.submitted = false;
isValid = false;
}
})
}
catch (error) {
this.loginForm = this.formBuilder.group({
username: [model.username, Validators.compose([Validators.required])],
password: ['', Validators.compose([Validators.required])]
});
this.submitted = false;
this.toast.ShowNotification('Something went wrong!', 'bottom');
}
}
}
ionViewWillEnter() {
if (this.isUserLoggin) {
this.nav.setRoot('welcome');
}
}
public gotoregister() {
this.nav.setRoot('register');
}
public gotoforget() {
this.nav.setRoot('forget');
}
public resetForm() {
this.submitted = false;
}
}
your
loader.present().then(() => {
});
is empty. Which means that your loader.dismiss() might activate before it is instantiated.
Try to put your try block in the call back of the present() function:
try {
etc...}
please Try with this
this.userService.loginUser(formData)
.then((res:any)=>{
//Success Code here
//Stop Loader
}).catch((err:any)=>{
//Error handling and Stop loader
})

VueFormGenerator, Custom Fieds didn't update value in model

I try to create my custom field.
so i do this :
import Vue from 'vue';
import Datepicker from 'vuejs-datepicker';
import VueFormGenerator from 'vue-form-generator';
Vue.component('fieldDatePicker', {
template: '<datepicker :placeholder="schema.placeholder" v-model="datePicker_model"></datepicker>',
components: {
Datepicker,
},
data: function() {
return {
datePicker_model: '',
};
},
mixins: [VueFormGenerator.abstractField],
mounted() {
this.datePicker_model = this.schema.default;
},
computed: {
value: {
get: function() {
return this.$moment(this.datePicker_model).format('DD-MM-YY')
},
set: function(newValue) {
throw 'TODO : ' + newValue;
// TODO converte and set value ! this.datePucker_model = newValue;
},
},
},
});
But my component didn't update the model of VueFormGenerator ...
What i forget ???
i add this to my component and it work ;)
watch: {
datePicker_model: function(newValue, OldValue) {
if(this.format(newValue) !== this.format(OldValue)) {
this.setModelValueByPath(this.schema.model, this.format(newValue));
}
},
},

ionic3 - Can't resolve all parameters for UserDataProvider: ([object Object], [object Object], ?)

This is Ionic3 project and I was doing login page.
This page I want to show login button first in slide menu, after I login into apps, hidden login button and showing logout button. But when I was doing it this error coming out:
Can't resolve all parameters for UserDataProvider: ([object Object],
[object Object], ?).
This is my ionic info:
Ionic Framework: 3.6.0
Ionic Native: 2.4.1
Ionic App Scripts: 2.1.3
Angular Core: 4.0.0
Angular Compiler CLI: 4.0.0
Node: 6.11.3
OS Platform: macOS Sierra
Navigator Platform: MacIntel
User Agent: Mozilla/5.0 (Macintosh; Intel
app.component.ts
import { Component, ViewChild } from '#angular/core';
import { Events, MenuController, Nav, Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { QQSDK, QQShareOptions } from '#ionic-native/qqsdk';
import { Facebook, FacebookLoginResponse } from '#ionic-native/facebook';
import { TabsPage } from '../pages/tabs/tabs';
declare var Wechat:any;
export interface PageInterface {
title: string;
name: string;
component: any;
icon: string;
logsOut?: boolean;
index?: number;
tabName?: string;
tabComponent?: any;
}
#Component({
templateUrl: 'app.html'
})
export class MyApp {
#ViewChild(Nav) nav: Nav;
appPages: PageInterface[] = [
{ title: 'News', name: 'TabsPage', component: TabsPage, index: 0, icon: 'ios-globe-outline' }
];
loggedInPages: PageInterface[] = [
{ title: 'News', name: 'TabsPage', component: TabsPage, index: 0, icon: 'ios-globe-outline' },
{ title: 'Logout', name: 'TabsPage', component: TabsPage, icon: 'log-out', logsOut: true }
];
userData = null;
rootPage = TabsPage;
pages: Array<{title: string, component: any}>;
constructor(public platform: Platform, public events: Events, public menu: MenuController,
private qq: QQSDK,private fb: Facebook) {
this.initializeApp();
this.userData.hasLoggedIn().then((hasLoggedIn) => {
this.enableMenu(hasLoggedIn === true);
});
this.enableMenu(true);
this.listenToLoginEvents();
}
openPage(page: PageInterface) {
let params = {};
if (page.index) {
params = { tabIndex: page.index };
}
if (this.nav.getActiveChildNavs().length && page.index != undefined) {
this.nav.getActiveChildNavs()[0].select(page.index);
} else {
// Set the root of the nav with params if it's a tab index
this.nav.setRoot(page.name, params).catch((err: any) => {
console.log(`Didn't set nav root: ${err}`);
});
}
if (page.logsOut === true) {
// Give the menu time to close before changing to logged out
this.userData.logout();
}
}
listenToLoginEvents() {
this.events.subscribe('user:login', () => {
this.enableMenu(true);
});
this.events.subscribe('user:signup', () => {
this.enableMenu(true);
});
this.events.subscribe('user:logout', () => {
this.enableMenu(false);
});
}
enableMenu(loggedIn: boolean) {
this.menu.enable(loggedIn, 'loggedInMenu');
this.menu.enable(!loggedIn, 'loggedOutMenu');
}
isActive(page: PageInterface) {
let childNav = this.nav.getActiveChildNavs()[0];
// Tabs are a special case because they have their own navigation
if (childNav) {
if (childNav.getSelected() && childNav.getSelected().root === page.tabComponent) {
return 'primary';
}
return;
}
if (this.nav.getActive() && this.nav.getActive().name === page.name) {
return 'primary';
}
return;
}
initializeApp() {
this.platform.ready().then(() => {
StatusBar.styleDefault();
Splashscreen.hide();
});
}
QQLogin(){
const loginOptions: QQShareOptions = {
client: this.qq.ClientType.QQ,
};
this.qq.ssoLogin(loginOptions)
.then((result) => {
console.log('shareNews success');
alert('token is ' + result.access_token);
alert('userid is ' + result.userid);
})
.catch(error => {
console.log(error);
});
this.qq.logout().then(() => {
console.log('logout success');
}).catch(error => {
console.log(error);
});
}
wechatLogin(){
let scope = "snsapi_userinfo",
state = "_" + (+new Date());
Wechat.auth(scope, state, function (response) {
// you may use response.code to get the access token.
alert(JSON.stringify(response));
}, function (reason) {
alert("Failed: " + reason);
});
}
weiboLogin(){}
FBLogin(){
this.fb.login(['email', 'public_profile']).then((response: FacebookLoginResponse) => {
this.fb.api('me?fields=id,name,email,first_name,picture.width(360).height(360).as(picture_large)', []).then(profile => {
this.userData = {email: profile['email'], first_name: profile['first_name'], picture: profile['picture_large']['data']['url'], username: profile['name']}
});
});
}
}
EDIT:
app.html
<ion-menu id="loggedOutMenu" [content]="content">
<ion-header>
<ion-toolbar color="danger">
<ion-title>菜单</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<ion-list-header>请登录</ion-list-header>
<button style="width:40%" ion-button round outline (click)= "QQLogin()">
<ion-icon name="minan-qq"></ion-icon>
</button>
<button color="wechat" style="width:40%" ion-button round outline (click)= "wechatLogin()">
<ion-icon name="minan-wechat"></ion-icon>
</button>
<button color="danger" style="width:40%" ion-button round outline (click)= "weiboLogin()">
<ion-icon name="minan-weibo"></ion-icon>
</button>
<button color="facebook" style="width:40%" ion-button round outline (click)= "FBLogin()">
<ion-icon name="minan-facebook"></ion-icon>
</button>
</ion-list>
<ion-list>
<ion-list-header>导航栏1</ion-list-header>
<button menuClose ion-item *ngFor="let p of appPages" (click)="openPage(p)">
<ion-icon item-start [name]="p.icon" [color]="isActive(p)"></ion-icon>
{{p.title}}
</button>
</ion-list>
</ion-content>
</ion-menu>
<ion-menu id="loggedInMenu" [content]="content">
<ion-header>
<ion-toolbar color="danger">
<ion-title>菜单</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-card *ngIf="userData">
<ion-card-header>账号</ion-card-header>
<ion-thumbnail>
<img [src]="userData.picture" />
</ion-thumbnail>
<ion-card-title>{{ userData.username }}</ion-card-title>
<!-- <ion-card-content>
<p>Email: {{ userData.email }}</p>
<p>First Name: {{ userData.first_name }}</p>
</ion-card-content> -->
</ion-card>
<ion-list>
<ion-list-header>导航栏2</ion-list-header>
<button menuClose ion-item *ngFor="let p of loggedInPages" (click)="openPage(p)">
<ion-icon item-start [name]="p.icon" [color]="isActive(p)"></ion-icon>
{{p.title}}
</button>
</ion-list>
</ion-content>
</ion-menu>
<!-- Disable swipe-to-go-back because it's poor UX to combine STGB with side menus -->
<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>
UPDATE:
app.module.ts
import { NgModule, ErrorHandler } from '#angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { QQSDK } from '#ionic-native/qqsdk';
import { Facebook } from '#ionic-native/facebook';
import { SocialSharing } from '#ionic-native/social-sharing';
import { PhotoViewer } from '#ionic-native/photo-viewer';
import { BrowserModule } from '#angular/platform-browser';
import { HttpModule } from '#angular/http';
import { OneSignal } from '#ionic-native/onesignal';
import { IonicStorageModule } from '#ionic/storage';
import { MyApp } from './app.component';
import { SosPage } from '../pages/sos/sos';
import { ServicesPage } from '../pages/services/services';
import { NewsPage } from '../pages/news/news';
import { NewsDetailPage } from '../pages/news-detail/news-detail';
import { ServicesDetailPage } from '../pages/services-detail/services-detail';
import { TabsPage } from '../pages/tabs/tabs';
import { InsurencePage } from '../pages/insurence/insurence';
import { InsurenceDetailPage } from '../pages/insurence-detail/insurence-detail';
import { EducationPage } from '../pages/education/education';
import { EducationDetailPage } from '../pages/education-detail/education-detail';
import { TravelPage } from '../pages/travel/travel';
import { TravelDetailPage } from '../pages/travel-detail/travel-detail';
import { InvestmentPage } from '../pages/investment/investment';
import { InvestmentDetailPage } from '../pages/investment-detail/investment-detail';
import { LifePage } from '../pages/life/life';
import { LifeDetailPage } from '../pages/life-detail/life-detail';
import { NewsDataProvider } from '../providers/news-data/news-data';
import { ServicesDataProvider } from '../providers/services-data/services-data';
import { UserDataProvider } from '../providers/user-data/user-data';
#NgModule({
declarations: [
MyApp,
SosPage,
ServicesPage,
NewsPage,
TabsPage,
NewsPage,
NewsDetailPage,
ServicesDetailPage,
InsurencePage,EducationPage,TravelPage,InvestmentPage,LifePage,
InsurenceDetailPage,TravelDetailPage,InvestmentDetailPage,EducationDetailPage,LifeDetailPage
],
imports: [
BrowserModule,
HttpModule,
IonicStorageModule.forRoot(),
IonicModule.forRoot(MyApp,{
})
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
SosPage,
ServicesPage,
NewsPage,
TabsPage,
NewsPage,
NewsDetailPage,
ServicesDetailPage,
InsurencePage,EducationPage,TravelPage,InvestmentPage,LifePage,
InsurenceDetailPage,TravelDetailPage,InvestmentDetailPage,EducationDetailPage,LifeDetailPage
],
providers: [{provide: ErrorHandler, useClass: IonicErrorHandler},
NewsDataProvider,
ServicesDataProvider,
SocialSharing,
PhotoViewer,
QQSDK,Facebook,
OneSignal,
UserDataProvider]
})
export class AppModule {}
user-data.ts
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import { Events } from 'ionic-angular';
import 'rxjs/add/operator/map';
#Injectable()
export class UserDataProvider {
HAS_LOGGED_IN = 'hasLoggedIn';
constructor(public http: Http, public events: Events, public storage: Storage) {
console.log('Hello UserDataProvider Provider');
}
login(username: string): void {
this.storage.set(this.HAS_LOGGED_IN, true);
this.setUsername(username);
this.events.publish('user:login');
};
signup(username: string): void {
this.storage.set(this.HAS_LOGGED_IN, true);
this.setUsername(username);
this.events.publish('user:signup');
};
logout(): void {
this.storage.remove(this.HAS_LOGGED_IN);
this.storage.remove('username');
this.events.publish('user:logout');
};
setUsername(username: string): void {
this.storage.set('username', username);
};
getUsername(): Promise<string> {
return this.storage.get('username').then((value) => {
return value;
});
};
hasLoggedIn(): Promise<boolean> {
return this.storage.get(this.HAS_LOGGED_IN).then((value) => {
return value === true;
});
};
}
please update your code file as below
user-data.ts
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import { Events } from 'ionic-angular';
import { Storage } from '#ionic/storage';
import 'rxjs/add/operator/map';
#Injectable()
export class UserDataProvider {
HAS_LOGGED_IN = 'hasLoggedIn';
constructor(public http: Http, public events: Events, public storage: Storage) {
console.log('Hello UserDataProvider Provider');
}
login(user: any): void {
this.storage.set(this.HAS_LOGGED_IN, true);
this.setUser(user);
this.events.publish('user:login');
};
signup(user: any): void {
this.storage.set(this.HAS_LOGGED_IN, true);
this.setUser(user);
this.events.publish('user:signup');
};
logout(): void {
this.storage.remove(this.HAS_LOGGED_IN);
this.storage.remove('username');
this.events.publish('user:logout');
};
setUser(user: any): void {
this.storage.set('user', user);
};
getUser(): Promise<any> {
return this.storage.get('user').then((value) => {
return value;
});
};
hasLoggedIn(): Promise<boolean> {
return this.storage.get(this.HAS_LOGGED_IN).then((value) => {
return value === true;
});
};
}
app.component.ts
import { Component, ViewChild } from '#angular/core';
import { Events, MenuController, Nav, Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { QQSDK, QQShareOptions } from '#ionic-native/qqsdk';
import { Facebook, FacebookLoginResponse } from '#ionic-native/facebook';
import { UserDataProvider } from '../src/to/user-data'
import { TabsPage } from '../pages/tabs/tabs';
declare var Wechat:any;
export interface PageInterface {
title: string;
name: string;
component: any;
icon: string;
logsOut?: boolean;
index?: number;
tabName?: string;
tabComponent?: any;
}
#Component({
templateUrl: 'app.html'
})
export class MyApp {
#ViewChild(Nav) nav: Nav;
appPages: PageInterface[] = [
{ title: 'News', name: 'TabsPage', component: TabsPage, index: 0, icon: 'ios-globe-outline' }
];
loggedInPages: PageInterface[] = [
{ title: 'News', name: 'TabsPage', component: TabsPage, index: 0, icon: 'ios-globe-outline' },
{ title: 'Logout', name: 'TabsPage', component: TabsPage, icon: 'log-out', logsOut: true }
];
//userData = null;
rootPage = TabsPage;
pages: Array<{title: string, component: any}>;
constructor(public platform: Platform, public events: Events, public menu: MenuController,
private qq: QQSDK,private fb: Facebook, private userData: UserDataProvider) {
this.initializeApp();
this.userData.hasLoggedIn().then((hasLoggedIn) => {
this.enableMenu(hasLoggedIn === true);
});
this.enableMenu(true);
this.listenToLoginEvents();
}
openPage(page: PageInterface) {
let params = {};
if (page.index) {
params = { tabIndex: page.index };
}
if (this.nav.getActiveChildNavs().length && page.index != undefined) {
this.nav.getActiveChildNavs()[0].select(page.index);
} else {
// Set the root of the nav with params if it's a tab index
this.nav.setRoot(page.name, params).catch((err: any) => {
console.log(`Didn't set nav root: ${err}`);
});
}
if (page.logsOut === true) {
// Give the menu time to close before changing to logged out
this.userData.logout();
}
}
listenToLoginEvents() {
this.events.subscribe('user:login', () => {
this.enableMenu(true);
});
this.events.subscribe('user:signup', () => {
this.enableMenu(true);
});
this.events.subscribe('user:logout', () => {
this.enableMenu(false);
});
}
enableMenu(loggedIn: boolean) {
this.menu.enable(loggedIn, 'loggedInMenu');
this.menu.enable(!loggedIn, 'loggedOutMenu');
}
isActive(page: PageInterface) {
let childNav = this.nav.getActiveChildNavs()[0];
// Tabs are a special case because they have their own navigation
if (childNav) {
if (childNav.getSelected() && childNav.getSelected().root === page.tabComponent) {
return 'primary';
}
return;
}
if (this.nav.getActive() && this.nav.getActive().name === page.name) {
return 'primary';
}
return;
}
initializeApp() {
this.platform.ready().then(() => {
StatusBar.styleDefault();
Splashscreen.hide();
});
}
QQLogin(){
const loginOptions: QQShareOptions = {
client: this.qq.ClientType.QQ,
};
this.qq.ssoLogin(loginOptions)
.then((result) => {
console.log('shareNews success');
alert('token is ' + result.access_token);
alert('userid is ' + result.userid);
})
.catch(error => {
console.log(error);
});
this.qq.logout().then(() => {
console.log('logout success');
}).catch(error => {
console.log(error);
});
}
wechatLogin(){
let scope = "snsapi_userinfo",
state = "_" + (+new Date());
Wechat.auth(scope, state, function (response) {
// you may use response.code to get the access token.
alert(JSON.stringify(response));
}, function (reason) {
alert("Failed: " + reason);
});
}
weiboLogin(){}
FBLogin(){
this.fb.login(['email', 'public_profile']).then((response: FacebookLoginResponse) => {
this.fb.api('me?fields=id,name,email,first_name,picture.width(360).height(360).as(picture_large)', []).then(profile => {
this.userData.login({email: profile['email'], first_name: profile['first_name'], picture: profile['picture_large']['data']['url'], username: profile['name']});
});
});
}
}