【发布时间】:2021-05-20 07:45:00
【问题描述】:
我正在开发一个 ionic angular android 应用程序,并使用 ngx translate,它可以在网络上完美运行,并通过终端安装到我的 android 手机上。但是当我创建一个apk并将其安装在我的手机上,或者从google play store下载已发布的apk时,在第一次运行应用程序时,翻译在应用程序上不起作用,当我关闭应用程序并重新打开时,它可以正常工作。有人说是关于角度延迟加载的事情,有人说是关于配置的事情,有人说是版本的事情,有人说不要使用 ./assets/i18n,使用不带 './' 的 assets/i18n。我也试过但同样的问题。这是我的代码:
我的 app.module:
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import {HttpClient, HttpClientModule,HTTP_INTERCEPTORS} from '@angular/common/http'
import {HTTP} from '@ionic-native/http/ngx'
import { TokenInterceptorService } from './core/interceptors/TokenInterceptor.service';
import { NativeStorage } from '@ionic-native/native-storage/ngx';
import { IonicStorageModule } from '@ionic/storage';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import {MatDialogModule} from '@angular/material/dialog';
import {MatButtonModule} from '@angular/material/button';
import {MatExpansionModule} from '@angular/material/expansion';
import {MatSelectModule} from '@angular/material/select';
import { MatCommonModule } from '@angular/material/core';
import {MatInputModule} from '@angular/material/input';
import { FormsModule } from '@angular/forms';
import {MatRadioModule} from '@angular/material/radio';
import {MatCheckboxModule} from '@angular/material/checkbox';
import {MatTabsModule} from '@angular/material/tabs';
import {MatTableModule} from '@angular/material/table';
import { DatePipe } from '@angular/common';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { HousekeepingrackComponent } from './core/components/alerts/housekeepingrack/housekeepingrack/housekeepingrack.component';
import { HousekeepingComponent } from './core/components/alerts/housekeeping/housekeeping.component';
import { SecurityComponent } from './core/components/alerts/security/security.component';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { IonicSelectableModule } from 'ionic-selectable';
import { EventService } from './core/services/event/Event.service';
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http, "./assets/i18n/", ".json");
}
@NgModule({
declarations: [AppComponent,HousekeepingrackComponent,HousekeepingComponent,SecurityComponent],
entryComponents: [],
schemas:[CUSTOM_ELEMENTS_SCHEMA],
imports: [
BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
HttpClientModule,
IonicStorageModule.forRoot(),
BrowserAnimationsModule,
MatDialogModule,
MatButtonModule,
MatExpansionModule,
MatSelectModule,
MatCommonModule,
MatInputModule,
FormsModule,
MatRadioModule,
MatCheckboxModule,
MatTabsModule,
MatTableModule,
IonicSelectableModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: (HttpLoaderFactory),
deps: [HttpClient]
}
})
],
providers: [
StatusBar,
SplashScreen,
EventService,
DatePipe,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
HTTP,
{
provide:HTTP_INTERCEPTORS,
useClass:TokenInterceptorService,
multi:true
},
NativeStorage
],
bootstrap: [AppComponent]
})
export class AppModule {}
这是我的 app-routing.module.ts:
import { NgModule } from '@angular/core';
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{
path: 'dasda',
redirectTo: 'folder/Inbox',
pathMatch: 'full'
},
{
path: 'folder/:id',
loadChildren: () => import('./folder/folder.module').then( m => m.FolderPageModule)
},
{
path: '',
loadChildren: () => import('./pages/login/login.module').then( m => m.LoginPageModule)
},
{
path: '',
loadChildren: () => import('./pages/traces/traces.module').then( m => m.TracesPageModule)
},
{
path: 'housekeeping/housekeepingrack',
loadChildren: () => import('./pages/housekeepingrack/housekeepingrack.module').then( m => m.HousekeepingrackPageModule)
},
{
path: 'housekeeping/rooms',
loadChildren: () => import('./pages/housekeeping/housekeeping.module').then( m => m.HousekeepingPageModule)
},
{
path: 'operation/security',
loadChildren: () => import('./pages/security/security.module').then( m => m.SecurityPageModule)
},
{
path: 'profile/search',
loadChildren: () => import('./pages/profile/profile.module').then( m => m.ProfilePageModule)
},
{
path: 'profilemodal',
loadChildren: () => import('./modalpages/profilemodal/profilemodal.module').then( m => m.ProfilemodalPageModule)
},
{
path: 'main/dashboard',
loadChildren: () => import('./pages/dashboard/dashboard.module').then( m => m.DashboardPageModule)
},
{
path: 'guest-search',
loadChildren: () => import('./modalpages/guest-search/guest-search.module').then( m => m.GuestSearchPageModule)
},
{
path: 'activities',
loadChildren: () => import('./pages/activities/activities.module').then( m => m.ActivitiesPageModule)
},
{
path: 'reservation',
loadChildren: () => import('./modalpages/reservation/reservation.module').then( m => m.ReservationPageModule)
},
{
path: 'alakart-modal',
loadChildren: () => import('./pages/alakart-modal/alakart-modal.module').then( m => m.AlakartModalPageModule)
},
{
path: 'iframe',
loadChildren: () => import('./modalpages/iframe/iframe.module').then( m => m.IframePageModule)
},
{
path: 'options',
loadChildren: () => import('./pages/options/options.module').then( m => m.OptionsPageModule)
},
{
path: 'accounting',
loadChildren: () => import('./pages/accounting/accounting.module').then( m => m.AccountingPageModule)
}
];
@NgModule({
imports: [
RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
],
exports: [RouterModule]
})
export class AppRoutingModule {}
在我的 app.component.ts 中:
import { Component, OnInit } from '@angular/core';
import { Platform, ToastController } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { EventService } from './core/services/event/Event.service';
import { HttpService } from './core/services/http/http.service';
import { MenuService } from './core/services/menu/menu.service';
import { CompanyService } from './core/services/company/company.service';
import { StorageService } from './core/services/storage/storage.service';
import { Router } from '@angular/router';
import { TranslatingService } from './core/services/translate/translate.service';
import { TranslateService } from '@ngx-translate/core';
import { LoadingService } from './core/services/loading/loading.service';
import { SharedService } from './core/services/shared/shared.service';
import { ThemeService } from './core/services/theme.service';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss']
})
export class AppComponent implements OnInit {
public selectedIndex = 0;
public userName: string = "";
public lastCompanyName: string = "";
public appPages = [];
public companies = [];
public userInfo: any;
public labels = ['Family', 'Friends', 'Notes', 'Work', 'Travel', 'Reminders'];
menuList: any[];
deviceLanguage: any;
isFromLogin: Boolean = false;
loaderInstance: any;
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
private loading: LoadingService,
private eventService: EventService,
private httpService: HttpService,
private menuService: MenuService,
private router: Router,
private sharedService: SharedService,
private translatingService: TranslatingService,
private companyService: CompanyService,
private storageService: StorageService,
private angularTranslateService: TranslateService,
private toastCtrl: ToastController,
private themeService: ThemeService,
private shared: SharedService) {
this.initializeApp();
this.storageService.getItem("themeColor").then(res => {
if (res) {
} else {
this.storageService.setItem("themeColor", "#8f074d")
}
this.themeService.setTheme()
})
this.shared.loaderObservable.subscribe(res => {
this.loaderInstance = res
})
this.eventService.isLoggedInObserved.subscribe(data => {
if (data) {
return this.FillCurrentAppPages(data.isLoggedIn).then(res => {
return res
}).catch(err => {
console.log("FillCurrentAppPages error", err)
});
}
});
this.storageService.getItem("appPages").then(appPages => {
this.appPages = appPages
}).catch(err => { })
this.storageService.getItem("GetAccountAndCompanyInfo").then(GetAccountAndCompanyInfo => {
// alert("GetAccountAndCompanyInfo cache "+ JSON.stringify(GetAccountAndCompanyInfo))
if (GetAccountAndCompanyInfo) {
this.userInfo = GetAccountAndCompanyInfo.UserInfo;
this.storageService.setItem('userInfo', this.userInfo);
this.IsHotelApiWorking();
this.userName = GetAccountAndCompanyInfo.UserInfo.UserName;
this.companies = GetAccountAndCompanyInfo.CompaniesAccounts;
this.storageService.setItem("companies", this.companies)
this.lastCompanyName = this.GetLastCompanyName(this.companies, GetAccountAndCompanyInfo.UserInfo.LastCompanyId);
GetAccountAndCompanyInfo.SidebarNavigations.forEach(nav => {
nav.submenu.forEach(sub => {
this.menuList.forEach(menu => {
if (menu.target == sub.target) {
this.appPages.push({ title: menu.name, url: menu.url, icon: menu.icon })
}
});
});
});
}
}).catch(err => { })
}
// ngOnDestroy() {
// console.log('destroy app comp');
// // this.onDestroy.next();
// }
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleDefault();
this.splashScreen.hide();
//cihazın dilini bulur ve çevirici servise ilgili parametreleri gönderip json dil dosyalarını kullanır
this.deviceLanguage = this.translatingService.languageSelectorFromStringToNumber(this.angularTranslateService.getBrowserLang())
// alert("dil: "+JSON.stringify(this.deviceLanguage))
this.storageService.setItem("LangID", this.deviceLanguage)
this.translatingService.switchLanguage(this.deviceLanguage)
});
}
GetAccountAndCompanyInfo(): Promise<any> {
return this.httpService.Post('v1/SednaMobileB2B/GetAccountAndCompanyInfo', {}).then(GetAccountAndCompanyInforesponse => {
// alert("GetAccountAndCompanyInfo api istek "+ JSON.stringify(GetAccountAndCompanyInforesponse))
if (GetAccountAndCompanyInforesponse) {
this.storageService.setItem("GetAccountAndCompanyInfo", GetAccountAndCompanyInforesponse)
this.userInfo = GetAccountAndCompanyInforesponse.UserInfo;
this.storageService.setItem('userInfo', this.userInfo);
this.IsHotelApiWorking();
this.userName = GetAccountAndCompanyInforesponse.UserInfo.UserName;
this.companies = GetAccountAndCompanyInforesponse.CompaniesAccounts;
this.storageService.setItem("companies", this.companies)
this.lastCompanyName = this.GetLastCompanyName(this.companies, GetAccountAndCompanyInforesponse.UserInfo.LastCompanyId);
const findPage = this.appPages.find(x => x.title == 'Dashboard');
if (!findPage) {
this.appPages.push({ title: 'Dashboard', url: '/main/dashboard', icon: 'home' })
}
GetAccountAndCompanyInforesponse.SidebarNavigations.forEach(nav => {
nav.submenu.forEach(sub => {
this.menuList.forEach(menu => {
if (menu.target == sub.target) {
if (menu.target == "bms.mobileb2b.dashboard") {
} else {
this.appPages.push({ title: menu.name, url: menu.url, icon: menu.icon })
this.storageService.SetPagePermissions(menu.target);
}
}
});
});
});
this.appPages.push({ title: 'Ayarlar', url: '/options', icon: 'settings' });
// this.appPages.push({ title: 'Accounting', url: '/accounting', icon: 'exit' })
this.appPages.push({ title: 'Çıkış Yap', url: '', icon: 'exit', type: 'exit' })
this.storageService.setItem("appPages", this.appPages)
this.router.navigateByUrl('/main/dashboard');
if (this.loaderInstance) {
console.log("loader instance: ", this.loaderInstance)
this.loaderInstance.loadingController.ctrl.dismiss()
}
this.eventService.publish({ name: 'refreshdashboard' });
return GetAccountAndCompanyInforesponse
}
}).catch(err => {
return err
if (this.loaderInstance) {
console.log("loader instance: ", this.loaderInstance)
this.loaderInstance.loadingController.ctrl.dismiss()
}
alert("getAccountAndCompanyInfos error " + JSON.stringify(err))
})
}
FillCurrentAppPages(isLoggedIn: boolean): Promise<any> {
if (isLoggedIn) {
this.appPages = [];
this.menuList = this.menuService.GetMobileMenuList();
return this.GetAccountAndCompanyInfo().then(res => {
return res
}).catch(err=>{
alert("fill current hata: "+JSON.stringify(err))
return err
})
}
}
GetLastCompanyName(companies: any, lastCompanyId: any): string {
var companyName: string = "Not Found";
companies.forEach(company => {
company.Companies.forEach(subCompany => {
if (subCompany.Id == lastCompanyId) {
companyName = subCompany.CompanyName;
return;
}
})
});
this.storageService.setItem("lastCompanyName", companyName)
this.sharedService.updateLastCompanyName(true);
return companyName;
}
changeCompany(subCompany): void {
this.loading.show().then(res => {
this.companyService.ChangeActiveCompany(subCompany.Id).then(response => {
this.storageService.getItem('token').then(token => {
this.httpService.Sedna360RefreshToken(token.refresh_token).then(refreshResponse => {
this.storageService.setItem('token', refreshResponse);
this.FillCurrentAppPages(true).then(res => {
this.loading.hide()
});
}).catch(err => {
alert("change company refresh token err: " + JSON.stringify(err))
});
})
});
})
}
async IsHotelApiWorking() {
this.storageService.getItem('userInfo').then(async userResponse => {
// alert("isotelapiworking "+ JSON.stringify(userResponse))
if (userResponse.IsHotelApiWorking == false) {
const toast = await this.toastCtrl.create({
message: 'Hotel bağlantı Hatası',
duration: 2000,
cssClass: 'failToast',
position: 'top'
});
toast.present();
}
});
}
selectedIndexFunc(i) {
this.selectedIndex = i;
var selectedMenu = this.appPages[i];
console.log(selectedMenu)
if (selectedMenu.type) {
if (selectedMenu.type == 'exit') {
this.storageService.removeAll()
}
}
}
ngOnInit() {
console.log("Buraya ne zaman geliyor.")
const path = window.location.pathname.split('folder/')[1];
if (path !== undefined) {
this.selectedIndex = this.appPages.findIndex(page => page.title.toLowerCase() === path.toLowerCase());
console.log("selected index app comp ", this.selectedIndex)
}
}
}
还有我的 package.json:
{
"name": "sednamobileb2b",
"version": "0.0.1",
"author": "Ionic Framework",
"homepage": "https://ionicframework.com/",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "~10.0.0",
"@angular/cdk": "^10.2.7",
"@angular/common": "~10.0.0",
"@angular/core": "~10.0.0",
"@angular/forms": "~10.0.0",
"@angular/material": "^10.2.7",
"@angular/platform-browser": "~10.0.0",
"@angular/platform-browser-dynamic": "~10.0.0",
"@angular/router": "~10.0.0",
"@capacitor/core": "2.4.2",
"@ionic-native/core": "^5.0.0",
"@ionic-native/http": "^5.31.1",
"@ionic-native/native-storage": "^5.31.1",
"@ionic-native/splash-screen": "^5.0.0",
"@ionic-native/status-bar": "^5.0.0",
"@ionic/angular": "^5.0.0",
"@ionic/storage": "^2.3.1",
"@ngx-translate/core": "^13.0.0",
"@ngx-translate/http-loader": "^6.0.0",
"@swimlane/ngx-datatable": "^18.0.0",
"cordova-sqlite-storage": "^5.1.0",
"ionic-selectable": "^4.7.1",
"ngx-spinner": "^10.0.1",
"rxjs": "~6.5.5",
"tslib": "^2.0.0",
"zone.js": "~0.10.3"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.1000.0",
"@angular/cli": "~10.0.5",
"@angular/compiler": "~10.0.0",
"@angular/compiler-cli": "~10.0.0",
"@angular/language-service": "~10.0.0",
"@capacitor/cli": "2.4.2",
"@ionic/angular-toolkit": "^2.3.0",
"@types/jasmine": "~3.5.0",
"@types/jasminewd2": "~2.0.3",
"@types/node": "^12.11.1",
"codelyzer": "^6.0.0",
"cordova-android": "^9.0.0",
"cordova-plugin-advanced-http": "^3.1.0",
"cordova-plugin-device": "^2.0.2",
"cordova-plugin-file": "^6.0.2",
"cordova-plugin-ionic-keyboard": "^2.2.0",
"cordova-plugin-ionic-webview": "^4.2.1",
"cordova-plugin-nativestorage": "^2.3.2",
"cordova-plugin-splashscreen": "^5.0.2",
"cordova-plugin-statusbar": "^2.4.2",
"cordova-plugin-whitelist": "^1.3.3",
"jasmine-core": "~3.5.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~5.0.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~3.0.2",
"karma-jasmine": "~3.3.0",
"karma-jasmine-html-reporter": "^1.5.0",
"protractor": "~7.0.0",
"ts-node": "~8.3.0",
"tslint": "~6.1.0",
"typescript": "~3.9.5"
},
"description": "An Ionic project",
"config": {
"ionic_sass": "./config/sass.config.js",
"ionic_copy": "./config/copy.config.js"
},
"cordova": {
"plugins": {
"cordova-plugin-nativestorage": {},
"cordova-plugin-whitelist": {},
"cordova-plugin-statusbar": {},
"cordova-plugin-device": {},
"cordova-plugin-splashscreen": {},
"cordova-plugin-ionic-webview": {
"ANDROID_SUPPORT_ANNOTATIONS_VERSION": "27.+"
},
"cordova-plugin-ionic-keyboard": {},
"cordova-plugin-advanced-http": {}
},
"platforms": [
"android"
]
}
}
我的翻译服务工作正常,我的意思是语言数据正确。我意识到必须至少更改一次根,但它看起来仍然无法正常工作,但是在更改一次根后,我关闭并重新打开应用程序,它可以随时完美运行。谁能告诉我如何解决这个问题?
【问题讨论】:
标签: angular ionic-framework ngx-translate