我是新的角,并已开始建立一个新的项目与下一个特点。如果解释不够清楚,很抱歉。我很高兴提供更多的信息,但不想通过我的整个项目有无关的信息。
我在用
我遵循了[https://github.com/ngx-translate/core][1]中提供的示例和说明
我的代码正在按预期工作,能够翻译4种语言,并在路由器内的多个组件中使用管道指令。这意味着我的json文件正在加载并被正确地构造。我看到了许多报告,其中json文件有错误,但这不是我的情况。
但是,我的问题是,我不能添加设置在构造函数中使用的默认语言和语言的行。
import { Component } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'app',
template: require('./app.component.html'),
styles: [require('./app.component.css')]
})
export class AppComponent {
constructor(private translate: TranslateService) {
translate.addLangs(["en", "fr", "es", "de"]);
//Error shows up when uncommenting any of the next two lines
//translate.setDefaultLang('en');
//translate.use('en');
}
}
每当我取消注释这些行时,我就会得到错误。
异常:调用Node模块失败,错误: SyntaxError: JSON.parse ()位置0处JSON中的意外令牌
如果我评论这些行,我的应用程序启动时就没有问题,唯一的细节就是语言还没有被设置。我可以在下拉列表中手动选择它,然后一切都如预期的那样工作。
以下是html文件
<div id="MainContainer" class='container-fluid'>
<div class='row'>
<label>
{{ "SELECT" | translate }}<br />
<select #langSelect (change)="translate.use(langSelect.value)">
<option *ngFor="let lang of translate.getLangs()" [value]="lang" [selected]="lang === translate.currentLang">{{ lang }}</option>
</select>
</label>
</div>
</div>
这是我的应用模块
import { NgModule } from '@angular/core';
import { UniversalModule } from 'angular2-universal'; // this automatically imports BrowserModule, HttpModule, and JsonpModule too.
import { Http } from '@angular/http';
import { FormsModule } from '@angular/forms'; // <-- ngModel lives here
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
// main Routing
import { AppRoutingModule } from './routers/app-routing.module';
// own Services
import { ImgService } from './services/img.service';
// own components
import { AppComponent } from './components/app/app.component';
import { NavMenuComponent } from './components/nav-menu/nav-menu.component';
import { CompleteSystemComponent } from './components/complete-system/complete-system.component';
import { VehicleComponent } from './components/vehicle/vehicle.component';
import { RobotComponent } from './components/robot/robot.component';
import { MapComponent } from './components/map/map.component';
import { StatusBarComponent } from './components/status-bar/status-bar.component';
import { RobotCameraComponent } from './components/robot-camera/robot-camera.component';
import { ImageProcessingComponent } from './components/image-processing/image-processing.component';
import { Station1Component } from './components/station1/station1.component';
import { Station2Component } from './components/station2/station2.component';
//AoT requires an exported function for factories
export function HttpLoaderFactory(http: Http) {
//return new TranslateHttpLoader(http, '/i18n/', '.json');
//return new TranslateHttpLoader(http, 'assets/i18n/', '.json');
return new TranslateHttpLoader(http);
}
@NgModule({
imports: [
UniversalModule, // must be first import. This automatically imports BrowserModule, HttpModule, and JsonpModule too.
FormsModule,
AppRoutingModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [Http]
}
}),
],
declarations: [
AppComponent,
NavMenuComponent,
RobotComponent,
VehicleComponent,
CompleteSystemComponent,
MapComponent,
StatusBarComponent,
RobotCameraComponent,
ImageProcessingComponent,
Station1Component,
Station2Component
],
providers: [
ImgService
],
bootstrap: [AppComponent]
})
export class AppModule {
}
如果有人能告诉我该怎么做,我会很感激的。到目前为止,这些都是我试图解决的问题
我怀疑问题在于json文件没有从wwwroot目录中加载,或者在应用程序启动时服务无法在那里找到它们。在应用程序启动后,它会发现它们没有问题,而且一切都如预期的那样工作。
再次感谢您的评论,并让我知道更多的信息是否有助于调试这个问题
发布于 2017-08-11 17:22:42
我最终成功地解决了这个问题的80% (我也是新手,希望看到更好的解决方案)。
这是我的app.module.shared.ts文件:
import { NgModule,Inject } from '@angular/core';
import { RouterModule,Router } from '@angular/router';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { HttpModule } from '@angular/http';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { AppComponent } from './components/app/app.component'
import { NavMenuComponent } from './components/navmenu/navmenu.component';
import { HomeComponent } from './components/home/home.component';
import { FetchDataComponent } from './components/fetchdata/fetchdata.component';
import { CounterComponent } from './components/counter/counter.component';
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http);
}
export const sharedConfig: NgModule = {
bootstrap: [ AppComponent ],
declarations: [
AppComponent,
NavMenuComponent,
CounterComponent,
FetchDataComponent,
HomeComponent,
],
imports: [
HttpClientModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
}),
RouterModule.forRoot([
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'counter', component: CounterComponent },
{ path: 'fetch-data', component: FetchDataComponent },
{ path: '**', redirectTo: 'home' }
])
]
};这是有趣的部分。唯一的问题是用户界面的转换是在浏览器中完成的,这对SEO不利。如果我想出了什么,我会更新的。
app.component.ts文件:
import { Component, OnInit, Inject } from '@angular/core';
import { PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
isBrowser: boolean;
constructor( @Inject(PLATFORM_ID) platformId: Object ,@Inject('ORIGIN_URL') originUrl: string, private translate: TranslateService) {
this.isBrowser = isPlatformBrowser(platformId);
if (this.isBrowser) {
translate.setDefaultLang('en');
translate.use('en');
}
}
changeLang(lang: string) {
this.translate.use(lang);
}
}这解决了它目前,如果你想出一个更好的解决方案,不会错过SEO分享它:)。
发布于 2017-09-18 15:03:42
我也有同样的问题,我就是这样解决的:
1)提供词汇以查看:
public async Task<IActionResult> Index()
{
var serverData = new IndexViewModel
{
Vocabulary = await GetUserLanguage()
};
return View(serverData);
}词汇表:
public class Vocabulary
{
public String Language { get; set; }
public Object Translations { get; set; }
}GetUserLanguage():
private async Task<Vocabulary> GetUserLanguage()
{
// Get lang form request headers
StringValues langs;
HttpContext.Request.Headers.TryGetValue("Accept-Language", out langs);
if(langs.Count == 0)
{
return null;
}
var langsArr = langs.ToArray();
for(var i = 0; i < langsArr.Length; i++)
{
var lang = langsArr[i];
if (lang.Contains("-"))
{
langsArr[i] = lang.Split("-")[0];
}
if (lang.Contains("_"))
{
langsArr[i] = lang.Split("_")[0];
}
}
langsArr = langsArr == null
? new String[] { "en" }
: langsArr;
Vocabulary vocabulary = null;
foreach (var userLang in langsArr)
{
var path = $"{_hostingEnvironment.WebRootPath}/assets/i18n/{userLang}.json";
FileInfo fileInfo = new FileInfo(path);
if (fileInfo.Exists)
{
vocabulary = new Vocabulary
{
Language = userLang,
Translations = await System.IO.File.ReadAllTextAsync(path)
};
break;
}
}
return vocabulary;
}2)将模型发送到boot.server。
Index.cshtml:
<app asp-prerender-module="ClientApp/dist/main-server" asp-prerender-data="@JavaScriptHelper.Json(Model)">Loading...</app>JavaScriptHelper.Json():
public static string Json(object obj)
{
JsonSerializerSettings settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Converters = new JsonConverter[]
{
new StringEnumConverter(),
},
StringEscapeHandling = StringEscapeHandling.EscapeHtml
};
return JsonConvert.SerializeObject(obj, settings);
}将数据从MVC传递到Angular2描述了here
在boot.server.ts中,您可以通过params.data: // Imports访问传递的服务器数据
declare var global: any;
enableProdMode();
export default createServerRenderer(params => {
let serverData = JSON.parse(params.data);
serverData.vocabulary.translations =
JSON.parse(serverData.vocabulary.translations);
global.serverData = serverData;
// ...
return platformDynamicServer(providers).bootstrapModule(AppModule).then(moduleRef => {
const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
const state = moduleRef.injector.get(PlatformState);
const zone = moduleRef.injector.get(NgZone);
return new Promise<RenderResult>((resolve, reject) => {
zone.onError.subscribe((errorInfo: any) => reject(errorInfo));
appRef.isStable.first(isStable => isStable).subscribe(() => {
// Because 'onStable' fires before 'onError', we have to delay slightly before
// completing the request in case there's an error to report
setImmediate(() => {
resolve({
html: state.renderToString(),
globals: {
serverData: serverData
}
});
moduleRef.destroy();
});
});
});对象global在节点环境中的预录制过程中可用。
globals: { serverData: serverData }过去的数据到窗口对象,该窗口对象在浏览器中可用
3)在app.component.ts中设置默认lang :宣告var serverData: any;
@Component({
selector: 'app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private translate: TranslateService, private http: Http, globalService: GlobalService, @Inject(PLATFORM_ID) platformId: Object) {
let isBrowser = isPlatformBrowser(platformId);
let lang = '';
let translations = { };
if (!isBrowser) {
lang = serverData.vocabulary.language;
translations = serverData.vocabulary.translations;
} else {
lang = (window as any).serverData.vocabulary.language;
translations = (window as any).serverData.vocabulary.translations;
}
translate.setTranslation(lang, translations);
translate.setDefaultLang(lang);
translate.use(lang);
}
}发布于 2020-12-22 15:48:21
<div id="MainContainer" class='container-fluid'>
<div class='row'>
<label>
{{ "SELECT" | translate }}<br />
<select #langSelect (change)="translate.use(langSelect.value)">
<option *ngFor="let lang of translate.getLangs()" [value]="lang" [selected]="lang === translate.currentLang">{{ lang }}</option>
</select>
</label>
</div>
</div>
https://stackoverflow.com/questions/44907376
复制相似问题