ionic3 - Не удается разрешить все параметры для UserDataProvider: ([object Object], [object Object],?)

Это проект Ionic3, и я делал страницу входа.

На этой странице я хочу сначала показать кнопку входа в меню слайдов, после входа в приложения, скрытую кнопку входа и отображение кнопки выхода. Но когда я это делал, вылезала ошибка:

Не удается разрешить все параметры для UserDataProvider: ([object Object], [object Object], ?).

Это моя ионная информация:

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']}
      });
    });
  }

}

РЕДАКТИРОВАТЬ:

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>

ОБНОВЛЕНИЕ:

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;
    });
  };
}

person Yuyang He    schedule 29.09.2017    source источник
comment
что такое storage:Storage? какое хранилище вы используете и где оно включено?   -  person Suraj Rao    schedule 29.09.2017
comment
«Хранилище», которое я не импортировал в «user-data.ts», если я импортирую его, выходит новая ошибка. Невозможно прочитать свойство «hasLoggedIn» null   -  person Yuyang He    schedule 29.09.2017
comment
«Хранилище» должно использоваться при вызове hasLoggedIn   -  person Yuyang He    schedule 29.09.2017
comment
Вы должны импортировать. Можете ли вы добавить модуль, в котором вы устанавливаете UserDataProvider в качестве поставщика?   -  person Suraj Rao    schedule 29.09.2017
comment
Вы имеете в виду добавить import { Storage } из '@ionic/storage'; в app.module.ts?   -  person Yuyang He    schedule 29.09.2017
comment
stackoverflow.com/a/43199528/4826457   -  person Suraj Rao    schedule 29.09.2017
comment
Я установил @ionic/[email protected], после импорта в app.module.ts появилась новая ошибка: Невозможно прочитать свойство forRoot неопределенного   -  person Yuyang He    schedule 29.09.2017
comment
После установки @ionic/[email protected] замените import { Storage } from '@ionic/storage'; на import { IonicStorageModule } from '@ionic/storage'; в app.module.ts   -  person Arpit Sancheti    schedule 29.09.2017
comment
@Arpit Sancheti У меня нет этого import { Storage } из '@ionic/storage';   -  person Yuyang He    schedule 29.09.2017
comment
import { Storage } from '@ionic/storage'; это должно быть в вашем user-data.ts   -  person Arpit Sancheti    schedule 29.09.2017
comment
Я вижу, я заменяю его из user-data.ts, показывает еще одну ошибку: Не удается разрешить все параметры для UserDataProvider: ([object Object], [object Object], ?).   -  person Yuyang He    schedule 29.09.2017
comment
не могли бы вы обновить вопрос с вашим новым кодом   -  person Arpit Sancheti    schedule 29.09.2017
comment
Давайте продолжим обсуждение в чате.   -  person Yuyang He    schedule 29.09.2017


Ответы (1)


пожалуйста, обновите файл кода, как показано ниже

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']});
      });
    });
  }

}

person Arpit Sancheti    schedule 29.09.2017
comment
Большое спасибо, ошибка устранена! Но почему, когда я запускаю 'ionic serve -l', отображается 'GET localhost:8100/null 404 (не найдено) ', эта ошибка не заражает запуск приложения в веб-браузере - person Yuyang He; 29.09.2017
comment
Когда я запускаю ionic cordova build ios --prod, появляется одно предупреждение: Предупреждение: не удается разрешить все параметры для хранилища в /Users/zzm/Desktop/minan/node_modules/@ionic/storage/es2015/storage.d.ts: ( ?). Это станет ошибкой в ​​Angular v5.x. - person Yuyang He; 29.09.2017
comment
вам не нужно беспокоиться об этом. Как и в случае с обновлением angular, ionic наверняка обновит плагин Storage. - person Arpit Sancheti; 29.09.2017
comment
хорошо, спасибо, но почему веб-браузер показывает «GET localhost: 8100/null 404 (Not Found)», когда я запускаю свой проект - person Yuyang He; 29.09.2017
comment
@yuyang, если ваша проблема решена, примите ответ - person Arpit Sancheti; 29.09.2017
comment
Могу ли я спросить, после того как я перейду на новый код, мой логин в facebook не работает, когда я нажимаю сторонний логин, который не может получить информацию о пользователе. Но прежде чем вы сможете получить ... Моя функция входа в систему через fb следующая: youtube.com/watch?v =Fw46diR8rAs - person Yuyang He; 14.11.2017
comment
Измените функцию входа в fb следующим образом: FBLogin(){ this.fb.login(['email', 'public_profile']).then(response => this.fb.api('me?fields=id,name,email,first_name,picture.width(360).height(360).as(picture_large)', [])) .then(profile => { console.log(profile); this.userData.login({ email: profile['email'], first_name: profile['first_name'], picture: profile['picture_large']['data']['url'], username: profile['name'] }); }).catch(error => console.log(error)); }); } и посмотрите вывод консоли. - person Arpit Sancheti; 14.11.2017