Angular: i18n: Kann Übersetzungsstrings außerhalb einer Vorlage verwenden

Erstellt am 7. Sept. 2016  ·  204Kommentare  ·  Quelle: angular/angular

Ich sende ein ... (mit "x" ankreuzen)

[x] feature request

Aktuelles Verhalten
https://github.com/angular/angular/issues/9104#issuecomment -244909246

Ich glaube nicht, dass es möglich ist, wie ich bereits sagte, es funktioniert nur mit statischem Text, es wird keinen Text im js-Code analysieren, nur Vorlagen

Erwartetes/erwünschtes Verhalten
Mithilfe einer API in der Lage sein, Zeichenfolgen zu übersetzen, die an beliebiger Stelle im Code verwendet werden.

Reproduktion des Problems

Was ist das erwartete Verhalten?
Ich beziehe mich auf die Verwendung von $translate.instant , um echte Anwendungsfälle aufzuzeigen:

  • Benutzerdefinierter gerenderter Text:
if (data._current_results === data._total) {
                content = this.$translate.instant('CLIPPINGS__LIST__SUMMARY_ALL', {'num': data._current_results});
            } else {
                if (undefined === data._total) {
                    data._total = '...';
                }

                content = this.$translate.instant('CLIPPINGS__LIST__SUMMARY', {
                    'num': data._current_results,
                    'total': data._total
                });
            }

            // Put 'mentions' first
            data = angular.merge({}, {
                mentions: mentions
            }, data);

            _.each(data, (value:number, key:string):void => {
                if (value) {
                    details += value + ' ' + this.$translate.instant('CLIPPINGS__LIST__SUMMARY_TYPE_' + key) + ', ';
                }
            });

            if (details) {
                details = '(' + _.trim(details, ', ') + ')';
            }

            content = content.replace(':details', details);

Mehr Beispiele:

  • Abrufen des Dateinamens des Bildes aus dem exportierten Bild eines HTML-gerenderten Berichts:
getExportImageName(hideExtension:boolean):string {
        let fileName:string;

        fileName = this.$translate.instant('D_CHART_FACET_authors__EXPORT_FILENAME', {
            'profileName': this.ExportService.GetProfileName(),
            'period': this.ExportService.GetPeriodString(this.SearchFilter.GetPeriodFromInterval())
        });

        if (!Boolean(hideExtension)) {
            fileName += '.png';
        }

        return fileName;
    }
  • Manchmal übersetzen Sie, manchmal verwenden Sie Modelldaten (könnten in einer Vorlage sehr ausführlich sein):
private _getTitle():string {
        if (this.inShareColumn) {
            return this.$translate.instant('COMPARISONS__SHARE_COLUMN_share_of_voice_TITLE');
        } else if (this.inTotalsColumn) {
            return this.$translate.instant('COMPARISONS__TOTAL_COLUMN_share_of_voice_TITLE');
        } else {
            return _.get<string>(this.group, 'profileName', '');
        }
    }
  • Verwenden eines Diagramm-Plugins eines Drittanbieters (Highcharts)
this.chart = new Highcharts.Chart(<any>{
            title: {
                text: this.$translate.instant('REPORTS_BLOG_MAPPING_CHART_TITLE_tone').toUpperCase(),
            },
            xAxis: {
                title: {
                    text: this.$translate.instant('REPORTS_BLOG_MAPPING_CHART_TITLE_tone_xaxis')
                }
            },
            yAxis: {
                min: 0,
                title: {
                    text: this.$translate.instant('REPORTS_BLOG_MAPPING_CHART_TITLE_tone_yaxis')
                }
            },
            plotOptions: {
                scatter: {
                    tooltip: {
                        headerFormat: '<b>{point.key}</b><br>',
                        pointFormat: '{point.y} ' + this.$translate.instant('REPORTS_BLOG_MAPPING_CHART_mentions')
                    }
                }
            }
        });
  • Um Konfigurationsvariablen einzurichten und den Text ohne Pipes zu rendern, da es sich nicht immer um eine übersetzte Zeichenfolge handelt
this.config = {
            requiredList: true,
            bannedList: false,
            allowSpaces: false,
            allowComma: false,
            colorsType: false,
            defaultEnterAction: 'required',
            requiredTooltip: this.$translate.instant('D_CLIPPING_TAGS__REQUIRED_TOOLTIP'),
            bannedTooltip: this.$translate.instant('D_CLIPPING_TAGS__BANNED_TOOLTIP')
        };
  • So setzen Sie window.title :) :
SetWindowTitle(title:string) {
        if (!!title) {
            this.$window.document.title = this.$translate.instant(title);
        }
    }
  • Benutzerdefinierte Datumsformatierung:
dateHuman(date:Date):string {
        return date.getDate() + ' ' + this.$translate.instant('GLOBAL_CALENDAR_MONTH_' + date.getMonth())
            + ' ' + date.getFullYear();
    }
  • Dinge nach übersetzten Werten sortieren:
// Sort types
            tmpTypes = _.sortBy(tmpTypes, (type:string):string => {
                // 'MISC' at the end
                if ('MISC' === type) {
                    return 'zzzzz';
                }

                return this.$translate.instant('FACET_phrases2__TYPE_' + type);
            });
GetSortedLanguages():IFacetLangDetectedCommonServiceLanguageObject[] {
        // We have to sort by translated languages!
        return _.sortBy(_.map(this.facetOptions, (item:string):any => {
            return {
                key: item,
                label: this.$translate.instant('FACET_langDetected_' + item),
                cssStyle: (_.includes(['english', 'catalan', 'spanish', 'french', 'italian'], item))
                    ? {'font-weight': 'bold'} : null,
                flag: _.get(this.lutFlags, item, null)
            };
        }), (item):string => {
            return item.label.toLowerCase();
        });
    }
  • Rohdaten mit übersetzten Werten nach CSV oder Excel exportieren:
getDataExportStacked(inputData:any):any {
        let exportData = angular.copy(inputData);

        if (angular.isArray(exportData) && exportData.length) {
            exportData[0].name = this.$translate.instant('CLIPPINGS__CHARTS_volume_TITLE');

            exportData[0].data = _.map(exportData[0].data, (inputDataItem:any):any => {
                return {
                    'label': inputDataItem.association.profileName,
                    'value': inputDataItem.value
                };
            });
        }

        return exportData;
    }
  • Legen Sie Konfigurationszeichenfolgen für Plugins von Drittanbietern fest:
UpdateCalendarStrings():void {
        Highcharts.setOptions({
            lang: {
                months: [
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_January'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_February'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_March'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_April'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_May'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_June'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_July'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_August'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_September'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_October'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_November'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_December')
                ],
                shortMonths: [
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Jan'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Feb'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Mar'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Apr'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_May'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Jun'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Jul'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Aug'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Sep'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Oct'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Nov'),
                    this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Dec')
                ],
                weekdays: [
                    this.$translate.instant('GLOBAL_CALENDAR_DAY_Sunday'),
                    this.$translate.instant('GLOBAL_CALENDAR_DAY_Monday'),
                    this.$translate.instant('GLOBAL_CALENDAR_DAY_Tuesday'),
                    this.$translate.instant('GLOBAL_CALENDAR_DAY_Wednesday'),
                    this.$translate.instant('GLOBAL_CALENDAR_DAY_Thursday'),
                    this.$translate.instant('GLOBAL_CALENDAR_DAY_Friday'),
                    this.$translate.instant('GLOBAL_CALENDAR_DAY_Saturday')
                ]
            }
        });
    }


Was ist die Motivation / der Anwendungsfall für die Änderung des Verhaltens?
In der Lage sein, Zeichenfolgen außerhalb von Vorlagen zu übersetzen.

Bitte teilen Sie uns Ihre Umgebung mit:

  • Winkelversion: 2.0.0-rc.6
  • Browser: [alle]
  • Sprache: [TypeScript 2.0.2 | ES5 | SystemJS]

@vicb

i18n feature high

Hilfreichster Kommentar

Ich denke, das ist ein echter Showstopper, i18n ist nicht einsatzbereit, bis dies implementiert ist.
Beispielsweise kann ich keine übersetzten Validierungsmeldungen im Code festlegen

Alle 204 Kommentare

Ich denke, das ist ein echter Showstopper, i18n ist nicht einsatzbereit, bis dies implementiert ist.
Beispielsweise kann ich keine übersetzten Validierungsmeldungen im Code festlegen

@ Mattes83 Hast du es so versucht?

<p [hidden]="!alertManagerRowForm.controls.sendTo.hasError('validateEmail')" class="help-error">
    {{ 'ALERTMANAGER__FORM__FIELD__sendTo__ERROR__validateEmail' | translate }}
</p>

:confused: Die Dokumentation sagt Ihnen, wie schön es ist, Fehlermeldungen im Code zu haben, und die Übersetzungsunterstützung erfordert alles in der Vorlage. Es scheint mehr Kommunikationsbedarf zu geben.

@marcalj Ich kenne diesen Weg ... aber ich muss lokalisierte Zeichenfolgen in meinen ts-Dateien haben.
@manklu Ich stimme voll und ganz zu

Ich denke, das ist ein echter Showstopper, i18n ist nicht einsatzbereit, bis dies implementiert ist.
Beispielsweise kann ich keine übersetzten Validierungsmeldungen im Code festlegen

Ja, auch hier, ich bin gerade von ng2-translate zu Angular2 i18n gewechselt, da ich lieber OOTB-Module verwende und es viel einfacher ist, Übersetzungen zu extrahieren (ng2-translate ist meiner Meinung nach zeitaufwändiger).
In diesem Stadium kann ich Fehlermeldungen, die von meinen Diensten ausgegeben werden, nicht übersetzen. Auch keine Abhilfe.

Wenn jemand eine Design-Spezifikation starten möchte, wäre es hilfreich (zB auf Google Docs).

Es müssten alle Fälle aufgelistet werden. Wenn ich schnell darüber nachdenke, sehe ich einen Bedarf für

_.('static text');
_.('with {{ parameter }}', {parameter: "parameter" });
_.plural(count, {'few': '...'});
_.select(on, {'value': '...'});

Hallo Leute, toller Funktionswunsch :+1:

Gibt es eine vorgeschlagene Problemumgehung zum Übersetzen von *.ts-Texten?

@fbobbio Ich habe versteckte Elemente in der Vorlage erstellt, z.
<span class="translation" #trans-foo i18n>foo</span> .

Binden Sie sie mit:
@ViewChild('trans-foo) transFoo : ElementRef; .

Rufen Sie dann den übersetzten Wert ab
transFoo.nativeElement.textContent .

Sieht retardiert aus, aber funktioniert für meine Bedürfnisse.

Da ng-xi18n bereits den gesamten TS-Code verarbeitet, warum nicht einen Decorator wie @i18n() für (String-)Properties implementieren? Diese könnten dann mit dem übersetzten Wert gefüllt werden, so wie @Input() mit unidirektionaler Datenbindung verwendet wird.
Wenn der nicht übersetzte Wert nicht einfach aus dem Code extrahiert werden kann, platzieren Sie ihn einfach wie folgt im Argument:

@i18n( {
  source : 'Untranslated value',
  description: 'Some details for the translator'
} )
public set translatedProperty( value : string ) {
   this._translatedProperty = value;
}

und die Quelle in die Eigenschaft einspeisen, wenn es kein Übersetzungsziel gibt.

Dies ist ein wesentlicher Punkt im gesamten Internationalisierungszyklus, IMO.

In meinem Shop sind wir an ein "ng-xi18n-ähnliches" Tool (eine Erweiterung von xgettext) gewöhnt, das alle Arten von Quelldateien durchsucht und nach markiertem Text sucht, der in Wörterbuchdateien für die Übersetzer eingefügt werden kann.

Ich liebe das saubere und einfache i18n-Markup in den HTML-Vorlagen, und ich hatte dasselbe für Typescript-Code erwartet.

@vicb Zusätzlich zu Ihren Anwendungsfällen denke ich über die Möglichkeit nach, die Lokalisierung von interpolierten Zeichenfolgen im TS-Code zu unterstützen. Es ist jedoch wahrscheinlich erforderlich, den TS-Code neu zu schreiben, um ein solches Szenario zu unterstützen. Wird es ein gültiger Ansatz sein?

Dies ist das Hauptmerkmal, das uns davon abhält, den Out-of-the-Box-Ansatz für die Übersetzung von Angular 2-Angeboten zu verwenden. Wir haben viele metadatengesteuerte Komponenten, deren Schlüssel aus einigen Metadaten stammen, die nicht in HTML gespeichert sind. Wenn wir per Pipe oder programmgesteuert gegen die verfügbaren TRANSLATIONS übersetzen könnten, könnten wir diese Komponenten dazu bringen, die richtigen Zeichenfolgen anzuzeigen.

In der Zwischenzeit sind wir aufgrund dieser Einschränkung auf etwas wie ng-translate beschränkt.

Ich habe dieses Problem umgangen, indem ich ein leeres „lang“-Objekt in einem Dienst hinzugefügt habe, der in meiner gesamten Anwendung verwendet wird. Ich wende dann eine Direktive an, die alle Spannen in einem div liest, und speichere den Wert in diesem Objekt. Ich platziere alle meine Zeichenfolgen in einer Vorlage am Ende der Seite mit einer versteckten Eigenschaft. Die Zeichenfolge ist dann von der Vorlage oder der Komponente aus erreichbar. Es ist hässlich und Sie könnten leicht einen Eintrag mit derselben ID überschreiben. Aber es ist besser als nichts.

BEDIENUNG

@Injectable()
export class AppService {

    //Language string object.
    private _lang:Object = new Object();
    get lang():Object {
        return this._lang;
    }
}

RICHTLINIE

@Directive({
    selector: '[lang]'
})
export class LangDirective implements OnInit {

    constructor(
        public element: ElementRef,
        public app: AppService) {
    }

    ngOnInit() {
        let ele = this.element.nativeElement;
        for (var i = 0; i < ele.children.length; i++) {
            let id = ele.children[i].getAttribute('id');
            let value = ele.children[i].innerHTML;
            this.app.lang[id]=value;
        }
    }
}

VORLAGE

<button>{{app.lang.myButtonText}}</button>
<div lang hidden >
    <span id="myButtonText" i18n="Test Button">Testing</span>
</div>

Hallo @lvlbmeunier

Vielen Dank für diesen Vorschlag für eine Problemumgehung, während wir auf die offizielle Implementierung warten. Ich habe versucht, Ihre Lösung zu implementieren, aber ich kann die dynamischen Übersetzungsschlüssel nicht erkennen. Ich habe versucht, es so zu machen:

<p *ngFor="let d of dataEntry">{{app.lang[d.name]}}</p>
<div lang hidden >
<span id="{{d.name}}" *ngFor="let d of dataEntry" i18n>{{d.name}}</span>
</div>

Diese neuen Schlüssel werden in meinen XLIFF-Dateien nicht angezeigt. Ist dies mit Ihrer Lösung möglich?

Ich habe es nie versucht, aber ich bin mir fast sicher, dass der Build der xliff-Datei keinen Code ausführt. Einen dynamischen Wert in i18n zu haben, würde dem Konzept widersprechen. Wenn Sie sicher alle Namen kennen, die in Ihrer Liste stehen würden, sollten sie alle unabhängig und nicht in einer for-Schleife deklariert werden.

Das manuelle Hinzufügen der Schlüssel funktioniert, ist aber unpraktisch. In meinem Fall erhalte ich Hunderte von Textschlüsseln, die von einer API übersetzt werden müssen.

Sie können Ihren Code ausführen und die Quelle nehmen und in eine Datei kopieren. Die Generierung der x18n-Datei basiert auf einer statischen Datei.

Mit 4.0.0-beta können Sie i18n eine ID zuweisen, zum Beispiel mainTitle:

<span i18n="title@@mainTitle">

Damit können wir zumindest für den JIT-Compiler eine Dummy-Komponente mit all unseren "zusätzlichen" Übersetzungen erstellen (sie muss nicht zum App-HTML hinzugefügt werden, sondern nur zum App-Modul).

Für den Anfang fügen wir die Anbieter nicht nur dem Compiler, sondern auch dem App-Modul hinzu:

// bootstrap.ts
getTranslationProviders().then(providers => {
    const options = { providers };
    // here we pass "options.providers" to "platformBrowserDynamic" as extra providers.
    // otherwise when we inject the token TRANSLATIONS it will be empty. The second argument of
   // "bootstrapModule" will assign the providers to the compiler and not our AppModule
    platformBrowserDynamic(<Provider[]>options.providers).bootstrapModule(AppModule, options);
});

Dann erstellen wir eine Dummy-Komponente für unsere zusätzlichen Übersetzungen. Vergessen Sie nicht, die Komponente zu declarations von AppModule hinzuzufügen. Dies ist so, dass ng-xi18n das HTML finden kann (glaube ich) und es der Übersetzungsdatei hinzufügen kann.

//tmpI18N.ts
import {Component} from '@angular/core';

@Component({
    selector: 'tmpI18NComponent',
    moduleId: module.id,
    templateUrl: 'tmp.i18n.html'
})
export class TmpI18NComponent {
}

Fügen Sie unsere Übersetzungen zu tmp.i18n.html :

<!-- tmp.i18n.html -->
<span i18n="test@@mainTitle">
    test {{something}}
</span>

Jetzt können wir einen Dienst erstellen, von dem wir unsere Übersetzungen abrufen können:

import {Injectable, Inject, TRANSLATIONS} from '@angular/core';
import {I18NHtmlParser, HtmlParser, Xliff} from '@angular/compiler';

@Injectable()
export class I18NService {
    private _source: string;
    private _translations: {[name: string]: any};

    constructor(
        @Inject(TRANSLATIONS) source: string
    ) {
        let xliff = new Xliff();
        this._source = source;
        this._translations = xliff.load(this._source, '');
    }

    get(key: string, interpolation: any[] = []) {
        let parser = new I18NHtmlParser(new HtmlParser(), this._source);
        let placeholders = this._getPlaceholders(this._translations[key]);
        let parseTree = parser.parse(`<div i18n="@@${key}">content ${this._wrapPlaceholders(placeholders).join(' ')}</div>`, 'someI18NUrl');

        return this._interpolate(parseTree.rootNodes[0]['children'][0].value, this._interpolationWithName(placeholders, interpolation));
    }

    private _getPlaceholders(nodes: any[]): string[] {
        return nodes
            .filter((node) => node.hasOwnProperty('name'))
            .map((node) => `${node.name}`);
    }

    private _wrapPlaceholders(placeholders: string[]): string[] {
        return placeholders
            .map((node) => `{{${node}}}`);
    }

    private _interpolationWithName(placeholders: string[], interpolation: any[]): {[name: string]: any} {
        let asObj = {};

        placeholders.forEach((name, index) => {
            asObj[name] = interpolation[index];
        });

        return asObj;
    }

    private _interpolate(pattern: string, interpolation: {[name: string]: any}) {
        let compiled = '';
        compiled += pattern.replace(/{{(\w+)}}/g, function (match, key) {
            if (interpolation[key] && typeof interpolation[key] === 'string') {
                match = match.replace(`{{${key}}}`, interpolation[key]);
            }
            return match;
        });

        return compiled;
    }
}

Jetzt können wir so etwas tun:

export class AppComponent {

    constructor(i18nService: I18NService) {
        // Here we pass value that should be interpolated in our tmp template as a array and 
        // not an object. This is due to the fact that interpolation in the translation files (xlf for instance)
        // are not named. They will have names such as `<x id="INTERPOLATION"/>
        // <x id="INTERPOLATION_1"/>`. And so on.
        console.log(i18nService.get('mainTitle', ['magic']));
    }
}

Dies ist eine hackige Problemumgehung. Aber zumindest können wir die Übersetzungsdatei nutzen, per Schlüssel abrufen, interpolieren und müssen kein verstecktes HTML in unserer Anwendung haben.

HINWEIS: Das aktuelle @angular/compiler-cli NPM-Paket von 4.0.0-beta hat eine falsche Abhängigkeitsversion von @angular/tsc-wrapped . Es zeigt auf 0.4.2, es sollte 0.5.0 sein. @vicb ist das leicht zu beheben? Oder sollten wir auf die nächste Veröffentlichung warten?

@fredrikredflag Super ! Und was ist mit AOT?

@ghidoz AOT ist eine andere Geschichte. Wir würden gerne alle Übersetzungen vorkompilieren, damit wir sie per Schlüssel erhalten können. Aber da ngc alle i18n durch die korrekte Übersetzung ersetzt, können wir sie nicht nutzen. Kann keine exponierten Optionen/Eigenschaften finden, die die geparsten Übersetzungen von ngc enthalten. Wir könnten den gleichen dynamischen Ansatz wie für JIT verwenden, indem wir die xlt-Datei auf diese Weise abrufen und sie dennoch auf dem TRANSLATION -Token bereitstellen. Dies widerspricht jedoch dem Zweck von AOT.

TUN SIE ES NICHT FÜR PRODUKTIONS-APPS .

/// bootstrap.aot.ts
function fetchLocale() {
    const locale = 'sv';
    const noProviders: Object[] = [];

    const translationFile = `./assets/locale/messages.${locale}.xlf`;
    return window['fetch'](translationFile)
        .then(resp => resp.text())
        .then( (translations: string ) => [
            { provide: TRANSLATIONS, useValue: translations },
            { provide: TRANSLATIONS_FORMAT, useValue: 'xlf' },
            { provide: LOCALE_ID, useValue: locale }
        ])
        .catch(() => noProviders);
}

fetchLocale().then(providers => {
    const options = { providers };
    platformBrowser(<Provider[]>options.providers).bootstrapModuleFactory(AppModuleNgFactory);
});

Aktuelle Überlegungen zur Umsetzung:

@Component()
class MyComp {
  // description, meaning and id are constants
  monday = __('Monday', {description?, meaning?, id?});
}
  • Da wir die DOM-Struktur mit einem solchen Konstrukt nicht beeinflussen könnten, könnten wir Laufzeitübersetzungen unterstützen - es gäbe eine einzige Version der Binärdatei und die Auflösung würde zur Laufzeit erfolgen.
  • Wir können auch statische Übersetzungen unterstützen, wie wir es heute für Vorlagen tun - Zeichenfolgen würden zur Kompilierzeit ersetzt, bessere Leistung, aber eine Version der App pro Gebietsschema,
  • wir könnten wahrscheinlich zu einem späteren Zeitpunkt __(...) in Templates unterstützen,
  • Dies würde über einen ab 2.3 verfügbaren TS-Transformator implementiert - wir könnten wahrscheinlich schon vorher einen Prototyp haben.

/cc @ocombe

Ich nehme an, dass __() für eine Methode steht, die noch keinen Namen hat (und die Methode wäre nicht wirklich __ , oder?)

Es ist eine gute Idee für statische Übersetzungen, die Sie in Ihren Klassen verwenden könnten, und ziemlich einfach zu implementieren, denke ich.

Nein __() ist der Name, gefällt es dir nicht :)

Es wird häufig in Übersetzungs-Frameworks verwendet - aber Sie können import {__ as olivier} from '@angular/core' verwenden, wenn Sie einen anderen Namen bevorzugen!

eeeeeeh es ist nicht sehr selbsterklärend :D
Es sieht aus wie eine sehr private Veranstaltung

Ich mag den Methodennamen ___ auch nicht :) Ich hatte mir vorgestellt, es wäre ein Dienst?
So oder so, es ist schön Fortschritte zu sehen 👍

Ich mag __()! :D Sehr gettext-y und es ist kurz.

In der JS-Welt habe ich nur Erfahrung mit @ocombes ng2-translate, wo das Markieren des gesamten Textes mit this._translateService.instant() den Code im Vergleich zu einer kürzeren Alternative, wie hier vorgeschlagen, etwas schwerer lesbar macht.

nichts hindert Sie daran, den ng2-Übersetzungsdienst umzubenennen __ Sie wissen schon :)

Eigentlich habe ich keine Ahnung, wie man eine DI-Service-Methode in eine einfache Funktion packt - egal, das würde den Rahmen dieser Ausgabe sprengen :-) Mein Kommentar war nur ein +1 für die Verwendung von __, da es bekannt ist, wenn Sie ' jemals andere Übersetzungs-Frameworks verwendet haben, zumindest in der PHP-Welt.

okay, vielleicht ist ___ in Ordnung, besser als "this.translationService.getTranslation()", viel kürzer.
Und ja, Sie können es umbenennen, wenn Sie möchten.

Was ist mit i18n(...) statt __(...) ?

Bitte hör auf mit der Namensdebatte, darum geht es nicht. Danke.

@vicb mit monday = __('Monday', {description: 'First day of the week', id: 'firstDatOfWeek'}); wird es möglich sein, es nach ID aufzulösen, dh:

__('@<strong i="8">@firstDatOfWeek</strong>') // Monday

Wäre Monday auch lokal für die definierte Klasse oder wäre es möglich, sie von überall aufzulösen? Ich denke an gängige Übersetzungen wie "schließen", "öffnen" etc.

Ich habe mich gefragt, was derzeit die beste Problemumgehung ist, die Sie für die Verwendung mit AOT empfehlen, bis die offizielle Version dies unterstützt.

Grüße,
Sean

Eckig 2 Küchenspüle: http://ng2.javascriptninja.io
und source@ https://github.com/born2net/Angular-kitchen-sink

@vicb Neuigkeiten, da drüben ^

Bis diese Funktion implementiert ist, verwende ich die Attributübersetzungsfunktion .

import {Component, Input, OnInit} from '@angular/core';

@Component({
    selector: 'app-sandbox',
    templateUrl: 'sandbox.html'
})
export class SandboxComponent implements OnInit {
    @Input()
    public title: string;

    constructor() {
    }

    ngOnInit() {
        console.log('Translated title ', this.title);
    }
}

Aus der übergeordneten Komponentenvorlage:

<app-sandbox i18n-title title="Sandbox"></app-sandbox>

Es ist eine Problemumgehung, aber ich denke, es ist bisher die sauberste. Es gibt Ihnen Zugriff auf die übersetzten title innerhalb ts .

Ich fange an, an dieser Funktion zu arbeiten, erwarte bald ein Designdokument :-)

Dies wird die am meisten erwartete Funktion sein

Das ist eine gute Nachricht. Danke @ocombe .

Das Designdokument ist hier verfügbar: https://goo.gl/jQ6tQf
Jedes Feedback ist willkommen, danke.

Süße, werde so schnell wie möglich lesen!

Danke @ocombe

Ich habe das Dokument gelesen. Schöne Zusammenfassung.

In der Lage zu sein, Strings aus ts-Dateien zu extrahieren, klingt großartig.

Ich bin mir nicht sicher, wann das Typescript-Upgrade für Angular4 verfügbar sein wird.

Dies bedeutet, dass diese Funktion bereits seit Monaten verfügbar sein sollte, da so ziemlich jeder, der auf diese Einschränkung gestoßen ist, diese Lösung nicht vor mindestens 3/6 weiteren Monaten verwenden kann.

Ich bin derzeit vielleicht nicht der einzige, der ngx-translate verwendet, um Übersetzungen in meinen Controllern zu verwalten, während ich mich für die Vorlagen auf Angular i18n verlasse.

Das Ziel, alles in i18n zusammenzuführen, ist natürlich großartig.

Aber abgesehen von der Vereinfachung in Bezug auf das Verständnis, wie man i18n im Winkel-Framework implementiert, wird dieser Ansatz wirklich die Leistung im Vergleich zur aktuellen ngx-translate-Implementierung steigern?

Nach meinem jetzigen Verständnis wäre der einzige Bonus, Strings aus Controllern extrahieren zu können.

Eine große Einschränkung ist im Moment auch die Pluralisierung, bitte stellen Sie sicher, dass es richtig funktioniert, wenn Sie das gesamte Upgrade veröffentlichen. Ich habe viele i18n-bezogene Tickets gelesen, bei denen sowohl xliff als auch xmb dies nicht richtig handhaben würden. Dies ist ein weiterer Fall, in dem ich zurück zu ngx-translate wechseln muss, um eine funktionierende Lösung zu liefern.

@ocombe Vielen Dank für das detaillierte Designdokument, das sieht nach einer wirklich guten Lösung für diese Feature-Anfrage aus. Das aktuelle Design adressiert die Anwendungsfälle, die ich zu lösen versuche.

Eine Frage: Das Design spricht von einem I18N-Dienst für den JIT-Modus und einem TS 2.2.x Transformer für den AOT-Modus. Gehe ich richtig in der Annahme, dass der Transformer sowohl den Aufruf der Dienstmethode durch eine statische Übersetzung ersetzt als auch alle verbleibenden Verweise auf den I18N-Dienst entfernt?

@Thommas Angular 4 verwendet TypeScript 2.1 (was bedeutet, dass Sie ein Upgrade durchführen müssen ), aber Sie können tatsächlich bereits jede neuere Version von TypeScript (z. B. 2.2.1) mit Angular 2 oder 4 verwenden.

In Bezug auf den Leistungsgewinn gegenüber ngx-translate hängt es davon ab, ob Sie AOT verwenden oder nicht. Wenn Sie AOT verwenden, ist dies ein Gewinn, aber Sie werden den Unterschied wahrscheinlich nicht sehen. In JIT (kein AOT) gibt es keinen Gewinn (eigentlich hängt es davon ab, ob Sie das Observable get oder die synchrone Methode instant verwenden, das Observable kostet mehr als ein einfacher Funktionsaufruf).
Ich spreche hier von i18n in Ihrem Code. Wenn wir über die Vorlagen sprechen, gibt es einen echten sichtbaren Gewinn, wenn Sie Angular i18n (in AOT und JIT) verwenden, da es keine Bindungen verwendet. Je mehr Übersetzungen Sie verwenden, desto mehr gewinnen Sie.

Ich werde dafür sorgen, dass die Pluralisierung genauso funktioniert wie bei Vorlagen. Gibt es derzeit ein Problem damit in den Vorlagen?

@schmuli Das einzige Mal, dass Angular Ihren Code ersetzen kann, ist, wenn Sie AOT verwenden. Wenn Sie dies nicht tun, bleiben die Serviceaufrufe in Ihrem Code gleich.
Wenn Sie jedoch AOT verwenden, wird der Dienstaufruf durch eine statische Übersetzung ersetzt (nur die Variablen, die Sie möglicherweise verwenden, bleiben dynamisch). Ich bin mir nicht sicher, ob wir Verweise auf den I18n-Dienst entfernen werden, da er in Zukunft für andere Dinge verwendet werden könnte. Ich muss sehen, was mit dem Transformator möglich ist, sobald ich mit dem Schreiben des Codes beginne. Denken Sie über einen Anwendungsfall nach, bei dem dies ein Problem wäre?

@ocombe Ich kann mir keinen Anwendungsfall vorstellen, bei dem das Verlassen des Codes ein Problem wäre, es sei denn, wir ziehen eine zusätzliche DI-Injektion in Betracht, die nicht verwendet wird (ist dies ein echtes Problem?).

In Anbetracht dessen, was Sie geschrieben haben, dass der Dienst in Zukunft für andere Dinge verwendet werden könnte, und das Potenzial für Fehler, die durch das Ändern des Codes des Benutzers eingeführt werden, würde ich sagen, dass es wahrscheinlich besser ist, das Entfernen von Code insgesamt zu vermeiden.

Vielleicht wäre es nützlich, den Dienst zu verwenden, um das aktuelle Gebietsschema in AOT zu erhalten. Stellen Sie sich zum Beispiel den Fall vor, dass Sie einen Server haben, der Text in mehreren Sprachen zurückgeben kann, daher müssen Sie das aktuelle Gebietsschema in die Anfrage aufnehmen. Sie können jedoch immer eine Dummy-übersetzte Zeichenfolge als Workaround verwenden.

@diego0020 Sie können das Gebietsschema bereits erhalten, fügen Sie einfach LOCALE_ID aus dem Kern ein

@ocombe Pluralization ist nicht mit xliff implementiert und niemand außerhalb von Google hat auch keine Ahnung, wie man es mit xmb verwendet. Siehe auch: https://github.com/angular/angular/issues/13780

Wie auch immer, derzeit blockiert nichts unsere i18n-Implementierung. ngx-translate mit einer Pluralisierungspipe wird vorerst ausreichen. Hoffentlich sieht alles in NG4 besser aus und die Dokumentation spiegelt die Verbesserungen wider. Danke.

@Thommas ICU mit xliff wird bald behoben: https://github.com/angular/angular/pull/15068 und wenn Sie wissen möchten, wie es verwendet wird, finden Sie es in der Dokumentation: https://angular.io/docs/ ts/latest/cookbook/i18n.html#! #Kardinalität

Bitte entschuldigen Sie, gibt es eine voraussichtliche Ankunftszeit? Weil ich gehört habe, dass es in der Version ng4.0.0 verfügbar sein wird, aber nein! Danke

Cc @ocombe

Wir arbeiten noch am Design, es gibt viele unerwartete Dinge zu berücksichtigen (z. B. wie Bibliotheken ihre eigenen Übersetzungen versenden könnten), ...
Erwarten Sie dies für 4.2, aber es ist nicht garantiert.

ok danke @ocombe , ich habe bitte zwei Fragen:

  1. Können wir tatsächlich Text in Vorlagen übersetzen, die eine Interpolation enthalten, wie:
    <span i18n>This is {{myValue}}</span>
  1. Ich frage, weil ich eigentlich nicht extrahieren kann, ich weiß nicht, warum ich diesen Fehler bekomme:
    Could not mark an element as translatable inside a translatable section

@istiti

  1. Ja, du kannst.
  2. Sie müssen auf die Position Ihrer i18n-Anweisung achten, sie sollte direkt auf dem Element platziert werden, das den Text enthält, nicht auf anderen Geschwistern.
    zum Beispiel:
    <div i18n><span i18n>my text</span></div> - das ist nicht gut
    <div><span i18n>my text</span></div> - das ist gut

@royiHalp
Danke

  1. Ok, wie mit Interpolation übersetzen?
  2. Wenn Sie ngc extrahieren, erhalten Sie eine Datei und ein Zeilen- und Code-Snippet, aber ich habe kein i18n, das in ein anderes i18n gewickelt ist
    Das ist wirklich schwer zu finden, welche meiner Eltern versehentlich i18n-Attribut haben

@istiti

  1. Sie machen es wie jedes andere Element, fügen Sie einfach die i18n-Direktive hinzu, wie Sie es getan haben:
    <span i18n>This is {{myValue}}</span>
    Das Ergebnis in der Datei messages.xlf lautet:
    <source>This is <x id="INTERPOLATION"/></source>
    Wenn Sie es jetzt in verschiedene Sprachen übersetzen, sollten Sie das <x id="INTERPOLATION"/> an der richtigen Stelle im Satz platzieren. Um anderen zu helfen, Ihre Bedeutung zu verstehen, können Sie der i18n-Direktive eine Beschreibung wie folgt hinzufügen:
  1. Aus meiner Erfahrung ist der Fehler Could not mark an element as translatable inside a translatable section so, wie ich es erklärt habe. Ich erinnere mich, dass ich feststellen kann, in welcher Datei ich das Problem habe, wenn ich den Fehler sorgfältig lese.

@fredrikredflag Tausend Dank!

Dein Code ist super nützlich! Ich musste nur ein Problem beheben, weil es scheint, dass xliff.load heutzutage ein anderes Objekt zurückgibt, also muss this._translations angepasst werden an:

const loaded = xliff.load(this._source, '');
this._translations = loaded['i18nNodesByMsgId'] ? loaded['i18nNodesByMsgId'] : {};

und eine geringfügige Validierung in der Methode get , wenn wir nach einem nicht vorhandenen Schlüssel fragen:

const placeholders = this._getPlaceholders(this._translations[key] ? this._translations[key] : []);

Außerdem denke ich, dass die leere i18n-Komponente am Baum geschüttelt wurde oder so, also musste ich die Zeichenfolgen in die entsprechenden Komponentenvorlagen einfügen mit:

<span hidden i18n="@@MY_STRING_1">String 1</span>
<span hidden i18n="@@MY_STRING_2">String 2</span>

Glücklicherweise brauche ich nur ein paar Strings für meine MiniApp, damit sie in der Produktion mit AoT hervorragend funktioniert.
Danke noch einmal!!!

P/S: das Tool xliffmerge von Martin Roob ist derzeit ein Must-Use und sein TinyTranslator auch B-)

Ich verwende die AoT-Kompilierung und mein Projekt unterstützt zwei Sprachen: Englisch und Russisch. Ich habe eine vorübergehende Lösung für das Problem gefunden, indem ich die Umgebungskonfiguration verwendet habe.

Die Datei environments/environment.ts enthält:

import { messagesEn } from '../messages/messages-en';

export const environment = {
  production: false
};

export const messages = messagesEn;

Außerdem gibt es zwei weitere Dateien environment.prod-en.ts und environment.prod-ru.ts mit dem nächsten Inhalt:

import { messagesEn } from '../messages/messages-en';

export const environment = {
  production: true
};

export const messages = messagesEn;

Und für Russisch:

import { messagesRu } from '../messages/messages-ru';

export const environment = {
  production: true
};

export const messages = messagesRu;

Jede Nachrichtendatei kann Folgendes enthalten:

export const messages = {
  MessageKey: 'Translation',
  AnotherMessageKey: 'Translation',
  Group: {
    MessageKey: 'Translation',
    AnotherMessageKey: 'Translation',
  }
};

In meinem Code (Komponenten, Dienste usw.) importiere ich nur Nachrichten:

import { messages } from '../../environments/environment';

Und benutze sie:

alert(messages.MessageKey);

In .angular-cli.json habe ich die nächsten Umgebungen für die Produktion angegeben:

"environments": {
  "dev": "environments/environment.ts",
  "prod-en": "environments/environment.prod-en.ts",
  "prod-ru": "environments/environment.prod-ru.ts"
}

Es klappt!

@alex-chuev Hast du das mit JIT versucht?

@ocombe eine grobe Schätzung, wann dies verfügbar sein würde?

Tolles Feature übrigens :)

Es wird ausgesetzt, bis Änderungen am Compiler vorgenommen werden, also nicht für 4.2, ich hoffe immer noch, dies für 4.3 zu machen

jemand weiß, wie man i18n in param-Werten zum Beispiel in [Titel] im folgenden Beispiel implementiert:
mit anderen Worten, fügen Sie dem Wort HALLO eine Übersetzung hinzu

Grüße

Sean

Wenn HELLO nur eine Zeichenfolge ist, die Sie in die HTML-Vorlage eingeben, können Sie Folgendes tun:
```html

````
Die Dokumentation enthält ein Beispiel dafür. Schau mal hier: https://angular.io/docs/ts/latest/cookbook/i18n.html#! #translate-attributes

Wenn Sie eine Zeichenfolgeneigenschaft in der Komponente binden müssen, müssen Sie auf diese Funktion warten oder (meines Wissens nach) eine benutzerdefinierte Art der Übersetzung implementieren.

@ocombe

Wir arbeiten noch am Design, es gibt viele unerwartete Dinge zu berücksichtigen (z. B. wie Bibliotheken ihre eigenen Übersetzungen versenden könnten), ...

Das ist sehr wichtig. Ich hoffe, es ist auch Teil dieser Funktion. Weil ich im Moment nicht sehe, wie eine Bibliothek von Drittanbietern Übersetzungen für Ihre Anwendung bereitstellen kann. Während des Builds können Sie nur 1 XLIFF-Datei angeben, und es scheint, dass Sie Ihre Bibliothek vorab erstellen müssen, damit Ihre Sprache sie übersetzen kann.

Ja, darauf warte ich auch! Dies ist SEHR wichtig für Projekte, die für ein nicht-englischsprachiges Publikum bestimmt sind!

Es ist definitiv etwas, das wir unterstützen wollen, das Team arbeitet an der Umgestaltung des Compilers, die uns das ermöglichen wird :-)

Gibt es eine Schätzung, für welche Version das Ziel sein wird? Ich habe irgendwo gelesen, dass es etwa 4,3 sein könnte?

Aufgrund der notwendigen Umgestaltung (und Breaking Changes) wird es nicht vor v5 sein, fürchte ich

Whaaaat 😳 Oh nein, ich warte auf dieses Feature für 4.2, wie du gesagt hast, und jetzt ist es für v5 ☹️ Ich dachte, für v5 wird es eine dynamische Sprachänderung geben, die nicht für jede Version veröffentlicht wird, aber ich hoffe trotzdem, dass es eines Tages sogar mit 36.000 verschiedenen Builds für jede Version sein wird Sprache. Ich frage mich nur, wann ist v5? Danke

@ocombe

@istiti Ich sagte, dass es kein garantiertes Datum war ;-)
Den Veröffentlichungsplan finden Sie hier: https://github.com/angular/angular/blob/master/docs/RELEASE_SCHEDULE.md
Die endgültige Version für v5 ist der 18.09.2017, aber es wird vorher Betas und RCs geben

Gibt es Änderungen, um eine Gebietsschemadatei für jede Komponente zu erstellen? bedeutet, erstellen Sie Chunks von messages.xlf , zum Beispiel: messages.{component}.{locale}.xlf und zum Beispiel nur messages.{component}.xlf für die Standardsprache.

Noch nicht

Der Schaden ist aufgrund der Bauzeit @ocombe streng minimal

Ich bin verwirrt... Ist diese Änderungsanfrage/Änderung offiziell oder nicht?
Das gleiche Problem hier, Übersetzungen gelten einfach nicht nur für Vorlagen.
Mit Redux, benutzerdefinierten Baumansichtskomponenten usw., die alle aus Javascript-Objekten IM CODE generiert werden, nicht pro Vorlage

Es ist offiziell und es kommt, aber wir mussten zuerst andere tiefgreifende Änderungen am Compiler vornehmen, weshalb er nicht für 4.3 bereit war

Ist bekannt, ab welcher genauen Version dieses Feature verfügbar sein wird/geplant ist? 4.3.1, 4.3.2 ... 4.3.X ?

Es gibt keine Major/Minor-Version mehr für den 4.x-Zweig (nur Patches: https://github.com/angular/angular/blob/master/docs/RELEASE_SCHEDULE.md), was bedeutet, dass dies für 5.x sein wird , bin mir nicht sicher welche.

Wird dies noch in 5.x erwartet? Ich kann es in den Betas nicht sehen. Danke

Könnte in v50.x sein, nicht in v5.x 😂

5.x ja, aber höchstwahrscheinlich nicht in 5.0

Le jeu. 3. August 2017 um 12:56 Uhr vltr [email protected] schriftlich:

Könnte in v50.x sein, nicht in v5.x 😂


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/angular/angular/issues/11405#issuecomment-319936876 ,
oder den Thread stumm schalten
https://github.com/notifications/unsubscribe-auth/AAQMorXMbyI8l6K3QA4jmXEKawiEC46xks5sUad0gaJpZM4J2pkr
.

Hallo @ocombe, ich bin sehr an dem Prozess interessiert, um dies zum Laufen zu bringen, und was an der Art und Weise, wie der Compiler derzeit arbeitet, macht dies zu einer schwierigeren Aufgabe. Haben Sie Klarheit darüber, wie die Zeitleiste aussieht, oder handelt es sich wahrscheinlich immer noch nicht um 5.0, sondern um 5.x?

@arackow es wird höchstwahrscheinlich in 5.x sein, @vicb arbeitet an den letzten Änderungen am Compiler, die dies endlich ermöglichen werden

@ocombe ... gibt es ein Designdokument, das ein Lösungskonzept für Zeichenfolgen außerhalb von Vorlagen beschreibt? Wir befinden uns in einer Projektentwicklungsphase, in der es großartig wäre, dies zu wissen, damit wir unsere temporäre Lösung irgendwie vorbereiten könnten und es später viel einfacher wäre, auf die endgültige Angular-Syntax umzusteigen.

Wir hatten ein Design-Dokument, aber es basierte auf der vorherigen Version des Compilers und es ist wahrscheinlich nicht die Implementierung, die wir am Ende machen werden. Wir werden ein neues öffentliches Designdokument erstellen, sobald wir eine bessere Vorstellung von der neuen Implementierung haben

@ocombe Ich muss dieser Funktion +1 geben. Ich brauche es jetzt dringend lol :+1: Danke, Leute, dass ihr tolle Tools gemacht habt! :)

Soweit ich das aktuelle Designdokument verstehe, müsste ein Autor einer AOT-Bibliothek die Übersetzungen für alle Sprachen bereitstellen, die von den verschiedenen Anwendungen benötigt werden, die diese Bibliothek verwenden.
Habe ich das richtig verstanden?

Das ist ein guter Punkt @gms1.
Ich habe das hier getestet.
Als Bibliotheksautor müssen Sie nur die i18n-Tags hinzufügen.
Sie sollten Ihre Bibliothek nicht zu „ ngfactories “ kompilieren (siehe Jason Adens Vortrag auf der ng-conf 2017), damit das Übersetzungs-Tag nicht ersetzt wird. Auf diese Weise erhalten Sie beim Ausführen des ng xi18n -Befehls auch eine Übersetzung im xliff für die Dateien in Ihrem node_modules-Ordner.

Also nein, Sie müssen keine Übersetzungen bereitstellen, sondern i18n-Tags mit nützlichen Bedeutungen hinzufügen.

Zitat aus dem Design-Dokument:

Für AOT wird der Quellcode transformiert, um die Serviceaufrufe durch statische Übersetzungen zu ersetzen. Dazu verwenden wir einen TypeScript-Transformator.

Was würde es also bedeuten, wenn eine Angular (AOT)-Bibliothek üblicherweise in transpilierter Form veröffentlicht wird? Ich habe in diesem Dokument keinen Verweis auf .metadata.json gefunden

Sie sollten Ihre Bibliothek nicht zum endgültigen Code kompilieren, sondern sie so vorbereiten, dass sie vom Entwickler mit Ihrem Code kompiliert werden kann. Sehen Sie, was @jasonaden hier erwähnt. Das bedeutet auch, dass Sie Ihre Bibliothek übersetzbar machen können, indem Sie das i18n-Tag hinzufügen.

@gms1 wie gesagt:

Wir hatten ein Design-Dokument, aber es basierte auf der vorherigen Version des Compilers und es ist wahrscheinlich nicht die Implementierung, die wir am Ende machen werden.

Und der AOT-Compiler wird für v5 umfassend geändert, es sollte für Bibliotheken einfacher sein, "aot-fähigen" Code zu veröffentlichen.
Für i18n wollen wir dies auch so einfach/flexibel wie möglich machen, es wird wahrscheinlich so aussehen: Bibliotheken können Übersetzungsdateien veröffentlichen, die Sie verwenden können, die Sie aber auch überschreiben können, wenn Sie dies bevorzugen, und Sie sollten in der Lage sein, sie bereitzustellen auch zusätzliche Sprachen, wenn die Bibliothek dies standardmäßig nicht unterstützt

Danke @ocombe für diese Klarstellung!

@ocombe Bedeutet dies, dass Funktionen von ngx-translate im Winkel selbst verfügbar sein werden?

@montreal91 keiner der Teile von ngx-translate kann unverändert in Angular implementiert werden, meine Bibliothek hat einen sehr naiven Ansatz, es funktioniert "meistens", aber wir wollen mit dem Framework viel effizienter sein.
Abgesehen davon bietet Angular ähnliche Funktionen (auch wenn die endgültige Implementierung anders sein wird).

Dies ist mein Ansatz (FLUX), während ich an einem UI-Benachrichtigungssystem arbeite, das auf (https://github.com/PointInside/ng2-toastr) basiert. Das Problem ist, dass der Benachrichtigungsinhalt im Serviceaufruf definiert wird und nicht in einer Vorlage, die vom eckigen i18n-System (xi18n) verwaltet werden soll.

Es ist nicht das, was ich gerne hätte, aber es ist eine _funktionierende_ Lösung. Sie können die Idee aus folgenden Codefragmenten _extrahieren_. Ich hoffe es hilft :)

irgendwo

// this call in any other component, service... 
// "info" method parameter is the "id" of the HTML element in template NotificationComponent.html
this.notificationActionCreator.success("myMessage");

NotificationComponent.ts

@Component({
    selector: 'notification-cmp',
    templateUrl: '../../public/html/NotificationComponent.html'
})
export class NotificationComponent implements OnInit, OnDestroy, AfterViewInit {

    notificationMap: Map<string, any> = new Map();
    subscription: Subscription;

    constructor(private toastr: ToastsManager,
                private vcr: ViewContainerRef,
                private store: NotificationStore,
                private elementRef: ElementRef) {

        this.toastr.setRootViewContainerRef(vcr);
    }

    ngOnInit() {
        this.subscription = this.store.payload
            .subscribe((payload: NotificationStorePayload) => this.handleStorePayload(payload));
    }

    ngOnDestroy(): void {
        this.store.destroy();
        if (null != this.subscription) {
            this.subscription.unsubscribe();
        }
    }

    ngAfterViewInit(): void {
        this.elementRef.nativeElement.querySelectorAll("div[notification-title][notification-text]")
            .forEach(el => this.notificationMap.set(el.id, {
                    title: el.attributes["notification-title"].value,
                    text: el.attributes["notification-text"].value,
                })
            );
    }

    handleStorePayload(payload: NotificationStorePayload): void {

        if (null != payload.action) {
            let notification = this.notificationMap.get(payload.notification.id);

            switch (payload.notification.type) {
                case NotificationType.SUCCESS:
                    this.toastr.success(notification.text, notification.title);
                    break;
                case NotificationType.INFO:
                    this.toastr.info(notification.text, notification.title);
                    break;
                case NotificationType.WARNING:
                    this.toastr.warning(notification.text, notification.title);
                    break;
                case NotificationType.ERROR:
                    this.toastr.error(notification.text, notification.title);
                    break;
            }
        }
    }
}

NotificationComponent.html

<div hidden
     id="myMessage"
     i18n-notification-title="@@notificationTitleMyMessage"
     i18n-notification-text="@@notificationTextMyMessage"
     notification-title="Greeting"
     notification-text="Hello world"></div>

<div hidden
     id="error"
     i18n-notification-title="@@notificationTitleError"
     i18n-notification-text="@@notificationTextError"
     notification-title="Error"
     notification-text="Something went wrong!"></div>

Jetzt, da Angular 5 veröffentlicht wurde, haben wir eine Wende, wann die Änderungen am i18n-Modul integriert werden?

Es sieht so aus, als ob dieses Feature von Änderungen am Winkel-Compiler abhängig ist, aber die für den Compiler verantwortlichen Teams scheinen weniger interessiert zu sein. Es sieht nicht so aus, als gäbe es eine Aufgabe oder einen PR oder Commits:- (. Entschuldigung für die Entlüftung, aber diese Feature-Anfrage, die sehr grundlegende Funktionen beschreibt, die in jedem anderen Übersetzungs-Framework vorhanden sind, ist jetzt mehr als ein Jahr alt. Ich habe gegeben hoffen, dass dieses wesentliche Feature kommt, zumindest für 5.x...

Jungs, bleibt ruhig. Es ist keine dumme Sache, es in einen AOT-Compiler zu implementieren. Haben Sie ein wenig Vertrauen, @ocombe sagte:

"es wird höchstwahrscheinlich in 5.x sein, @vicb arbeitet an den letzten Änderungen am Compiler, die dies endlich möglich machen werden"

Ja, wir arbeiten gerade an der Runtime i18n, was der erste Schritt ist.
Runtime i18n bedeutet: ein Bündel für alle Sprachen, AOT-kompilierte Bibliotheken können i18n verwenden, und vielleicht später die Möglichkeit, die Sprache zur Laufzeit zu ändern. Es bedeutet auch, dass wir Übersetzungen zur Laufzeit durchführen können, was für Übersetzungen innerhalb des Codes benötigt wird (weil wir einen Laufzeitparser für Übersetzungen usw. benötigen).
Sobald dies erledigt ist, werden Übersetzungen innerhalb des Codes die nächste Priorität sein.

Aber wir konnten Laufzeit-i18n nicht ausführen, bevor wir den Compiler so geändert haben, dass Typoskript-Transformatoren verwendet werden (was für 5.0 getan wurde).

Irgendeine Idee, welche 5.x-Version welche i18n-Verbesserungen haben wird? Wird irgendetwas mit 5.0.0 selbst veröffentlicht?

5.0:

  • neue i18n-Pipes (Datum/Zahl/Prozent/Währung), die nicht die intl-API verwenden, die ungefähr 20 Fehler behoben hat, weil sie jetzt in allen Browsern gleich funktionieren + einige andere Verbesserungen (Gebietsschemaparameter, neue zusätzliche Formate, Zeitzonenparameter für die Dattelpfeife, ...)
  • neue i18n-API-Funktion für Bibliotheken und Komponenten: https://next.angular.io/api?query=getlocale
  • bessere Integration mit dem CLI

5.1 oder 5.2 (wenn es keinen unerwarteten Blocker gibt):

  • Laufzeit i18n

5.x:

  • i18n-Code-Übersetzungen (nicht nur Vorlage)

Und andere Dinge, die wir im Laufe der Zeit hinzufügen werden, aber noch nicht entschieden sind (Sie können https://github.com/angular/angular/issues/16477 folgen).

Nur neugierige Gedanken, obwohl ich ein bisschen spät bin, nur wenn wir die i18n-Unterstützung in einer TS-Datei in Betracht ziehen, warum denken wir nicht über die Anmerkungssyntax nach? (Ich habe festgestellt, dass es oben auch von jemandem erwähnt wurde)

Beispiel wäre:
@i18n (id='message1')
message1 = "Dies ist eine Nachricht, die übersetzt werden muss";

@i18n (id='dynamischeNachricht')
dynamicMessage = "Dies ist eine dynamische Nachricht mit {0}";

Mit der Annotation für dynamicMessage können wir eine Funktion durch Annotation in diese String-Instanz einfügen, deren Name format ist, dann können wir wie folgt verwenden:
var finalMessage = dynamicMessage.format('value1')

Ein ähnlicher Ansatz könnte für die Pflege benannter Parameter usw. möglich sein.

Ich denke, die Frage ist nicht, wie man eine gute Entwicklererfahrung macht. Die Frage bezieht sich auf die Zusammenstellung.

Was passiert auch, wenn Sie message1 in eine andere Zeichenfolge ändern? Alle i18n-Variablen müssen dann immer Konstanten sein. Ich glaube nicht, dass die Verwendung von Variablen überhaupt funktionieren würde. Beispielsweise hat Symfony einen Übersetzerdienst mit einer Übersetzungsfunktion, die in JS-Syntax wie folgt funktionieren würde: let translated = this.translator.trans('Hello %name%', [{'%name%': nameVariable}]); was zu: <source>Hello %name%</source> <target>Bonjour %name%</target> führt

@MickL Der Punkt der aktuellen -aot-Übersetzung ist, ein minimales und effizientes Programm zu erstellen. Deshalb gibt es noch keinen Ansatz zur dynamischen Übersetzung.
Ich bin der festen Überzeugung, dass der aktuelle Ansatz wirklich gut ist, in dem Sinne, dass wir keinen Dynamikdienst verwenden, um Zeichenfolgen zu übersetzen. Das heißt, wenn Sie wissen, dass ein Text statisch ist, übersetzen Sie ihn bitte auf diese Weise, ohne einen Dienst zu verwenden.

Das Problem mit der dynamischen Übersetzung ist einfach, wenn Sie eine Zeichenfolge jedes Mal übersetzen, wenn Sie sie anzeigen. Ist kein wirklich guter Weg,
Warum?

  1. Weil Sie ein Wörterbuch mehrerer Sprachen im Gedächtnis haben, wenn Sie es nicht verwenden.
  2. Jedes Mal, wenn Sie einen dynamischen Text anzeigen, müssen Sie zur Karte gehen und einen Schlüssel finden und dann die Sprachübersetzung finden. JEDES MAL, weil Sie eine "Hauptsprache" haben.

Aus meiner Sicht sollte die zukünftige Lösung lauten:

  1. Das Backend gibt Ihnen den Text, den Sie übersetzen möchten.
  2. Ersetzen/(oder laden Sie vom Backend herunter, was der aktuelle Ansatz ist) jeden Text, den Sie in der aktuellen/Hauptsprache anzeigen. ( Ersetzen Sie alles rechtzeitig, aber Sie müssen nicht jedes Mal zwei Schlüssel finden, wenn Sie ein einfaches Etikett anzeigen möchten).
  3. Nur wirklich dynamischer Text kann ersetzt und/oder an das Backend angefordert werden.

Denken Sie darüber nach, wenn Sie wirklich dynamischen Text zum Anzeigen haben, können Sie ihn vom Backend erhalten, und wenn Sie wirklich eine Kopie dieses "dynamischen Texts" benötigen, können Sie dafür immer den Cache verwenden.

Meiner Meinung nach braucht man dieses Thema nicht mehr zu diskutieren. Tatsächlich arbeitet ein Typ (Olivier Combe) VOLLZEIT an i18n. AOT ist etwas ganz Besonderes und es musste viel Arbeit geleistet werden, bevor dieses Problem auch nur annähernd möglich wurde. Bald werden wir dynamische Übersetzungen haben: Sie müssen nicht mehr jede Sprache separat erstellen! Wenn dies erledigt ist, werden wir später Übersetzungen innerhalb des Codes (dieses Problem) haben. Er sagte, der Weg bis zur Lösung dieses Problems werde von nun an hoffentlich ein halbes Jahr dauern.

Wenn Sie interessiert sind, schauen Sie sich seine Rede auf Angular Connect am 07.11.17 über Gegenwart und Zukunft von i18n in Angular an: https://youtu.be/DWet6RvhHWI?t=21m12s

Das riecht nach einem guten Anwendungsfall für Template-Strings mit Typoskript-Tags ...

Das stinkt allgemein. Ich besuche diesen Thread einmal im Monat, um den Fortschritt zu überprüfen, und bin nicht mehr enttäuscht, weil ich die Erwartungen gesenkt habe. Das einzige, was Entwickler wollen, ist, die gleichen Optionen für die Zeichenfolgenübersetzung im Code wie in Vorlagen zu haben. Aufgrund dieser fehlenden Funktionalität ist mein Code mit versteckten übersetzten Vorlagenzeichenfolgen durchsetzt. Ob dies letztendlich mit einem Dienst oder Anmerkungen erreicht wird, ist irrelevant und es spielt keine Rolle, ob es eine Millisekunde länger dauert. Ich beobachte bereits etwas auf Änderungen, wenn ich eine Zeichenfolge aus dem Code auswähle. Die einzige Voraussetzung ist, dass der Code geparst wird und die relevanten Strings in denselben Dateien mit demselben Format wie meine vorlagenbasierten Übersetzungen landen.

@eliasre Sie können https://github.com/ngx-translate/i18n-polyfill ausprobieren, wenn Sie es mit der Codeübersetzung eilig haben
keine Versprechungen, dass es dasselbe sein wird, tatsächlich wird es wahrscheinlich anders sein (wie einfacher zu bedienen), es gibt Einschränkungen für das, was derzeit möglich ist ... und es wird ~ 80ko zu Ihrer App hinzufügen diese lib

Sie können ngx-translate verwenden, wenn Sie nicht warten möchten

@ocombe würde es Ihnen etwas ausmachen, Updates über den Fortschritt bereitzustellen, damit wir die Entwicklungszeitpläne verfolgen und entsprechend planen können, wenn wir auf Entscheidungen warten, welche Plugins oder Frameworks verwendet werden sollen? es wäre sehr hilfreich und geschätzt

@eliasre Ich denke, Google möchte sofort eine gute Lösung finden. Ohne Änderungen in der Zukunft zu brechen. Ich stimme zu, dass es länger dauert, als wir denken.

Stört den armen @ocombe nicht, er arbeitet sehr SEHR hart!
Mach weiter! :)

Ich bin nicht diejenige, die an dieser Funktion arbeitet, und es sind Ferien, ich werde Sie wissen lassen, sobald ich mehr weiß

danke @ocombe

danke @ocombe , alle Updates würden hier sehr geschätzt. Ich habe in den letzten Monaten verzweifelt auf Runtime i18n gewartet, und die letzte Build-ETA war 5.2. Können Sie uns bitte mitteilen, sobald Sie hier eine aktualisierte ETA haben?

Tut mir leid, dass ich so hartnäckig bin, aber das Bauen für 20 Sprachen ist im Moment quälend langsam.

Da Angular 5.2 draußen ist und ich leider nichts zu i18n finden konnte (oder habe ich etwas übersehen?) ... - @ocombe könnten Sie uns vielleicht über den Veröffentlichungsplan auf dem Laufenden halten? Vielen Dank und vielen Dank für Ihre Bemühungen auf i18n!

@ocombe ist nicht der Typ, auf den wir hier warten ... sehen Sie sich den YouTube-Link in diesem Kommentar an: https://github.com/angular/angular/issues/11405#issuecomment -343933617

Die Planung entwickelt sich ständig weiter. Immer wenn ich ein voraussichtliches Veröffentlichungsdatum nenne, stellt sich heraus, dass etwas anderes die Priorität erhält oder erforderlich wird, und es verschiebt das Datum erneut. Ich weiß, wie enttäuschend es für Sie alle ist, die auf dieses Feature warten, und ich tue alles, was ich kann, um die Priorität zu erhöhen.
Wir haben morgen ein Treffen, um den Rückstand/die Planung von i18n zu besprechen. Ich werde Sie wissen lassen, wenn ich etwas Neues erfahre.

@ocombe , wenn i18n diesen Monat veröffentlicht wird, kaufe ich dir eine 24er-Packung Craft Beer

Ich füge 24 Flaschen deutsches Bier und weitere 24 Flaschen hinzu, wenn Sie fragen, was Angular Elements und die Bibliotheksunterstützung tun. Verdammt, keine Informationen zu bekommen, was los ist, ist schrecklich.

@ocombe Sie haben diese seltene einmalige Gelegenheit, 72 Flaschen teures Craft-Bier zu erwerben und die Entwicklungsgemeinschaft glücklich zu machen. Wir werden unsere Versprechen erfüllen, wenn Sie diese Dinge tun, mein Freund.

@MickL Angualr Elments, so wie ich es verstehe, wird es uns ermöglichen, Nicht-SPA-Seiten zu erstellen und Winkelkomponenten als native Elemente (auch als Selbst-Widgets) zu verwenden.

Ja, ich weiß. Dies sind 2 weitere Funktionen, auf die alle warten, aber niemand weiß, wie der Status ist und wann er zu erwarten ist ...

Wenn nur jemand verspricht, die letzten 27 Flaschen Bier hinzuzufügen, können wir anfangen, sie herunterzuzählen!
http://www.99-bottles-of-beer.net/language-javascript-1948.html

Ich werde sie hinzufügen, @ocombe : Nenne deine Lieblingsmarke: D

Bearbeiten: Jemand erstellt einen ähnlichen Dienst wie eth bounty namens beerbounty: p

Wie versprochen ein kleines Update: Wir streben nach wie vor an, Runtime i18n in v6 zu veröffentlichen, was uns 5 Wochen Zeit gibt. Es wird kurz sein, es wird wahrscheinlich in einer der letzten Versionen hinzugefügt werden, und es wird hinter einer Flagge sein.
Runtime i18n sollte mit Codeübersetzungen geliefert werden, da es so sowieso auch für Vorlagen funktioniert (es sollte denselben Mechanismus verwenden).
Davon abgesehen ist es nicht sicher, ob der Dienst zu 100 % bereit sein wird, und wir könnten ihn verschieben, um sicherzustellen, dass wir ihn nicht gleich nach der Veröffentlichung kaputt machen, wenn wir das Gefühl haben, dass dies die richtige Wahl ist. Aber es wird auf jeden Fall der Laufzeit i18n folgen (das ist unsere Roadmap), und wir brauchen keine Hauptversion, um es zu veröffentlichen, weil es hinter einer Flagge sein wird und es sowieso nichts kaputt machen sollte).

Was uns daran hindern könnte, es rechtzeitig zu veröffentlichen:

  • wenn wir auf ein unerwartetes Problem stoßen (Sie wissen, wie Entwicklung funktioniert)
  • wenn es die internen Google-Apps kaputt macht, weil wir irgendwo etwas vermasselt haben
  • wenn etwas mit höchster Priorität kommt und wir unseren Fokus ändern müssen
  • wenn eines der neuen Dinge, von denen es abhängt, blockiert oder verzögert ist (Laufzeit i18n hängt von einigen wichtigen internen Änderungen ab, an denen andere Mitglieder des Teams arbeiten)
  • Leitender AngularJS-Entwickler, verwendet PascalPrechts Translate-Bibliothek seit 3 ​​Jahren.
  • Hat mich begeistert. Winkel 2 Anfänger. Naives Surfen auf https://angular.io/guide/i18n
  • Erfolgreiche Integration von i18n in mein berufliches Projekt
  • Verbringen Sie einen ganzen Tag damit, mit all den fest codierten Front-End-Etiketten herumzuspielen und sie in eine über 100 kb große xlf-Datei zu portieren
  • In der Notwendigkeit, Rohetiketten innerhalb von ng-Diensten zu übersetzen
  • Wenn Sie es bei Google nachschlagen, seien Sie hier
  • Finden Sie heraus, dass es keine Lösung gibt, bevor Angular 6 altert.
  • ich rn
    mfw

@Macadoshis Sie können jetzt meine Polyfill-Bibliothek verwenden: https://github.com/ngx-translate/i18n-polyfill

@Macadoshis jetzt stell dir vor, was wir seit alpha.46 durchgemacht haben! ;)

Vielen Dank, dass Sie mir @ocombe auf i18n- polyfill verwiesen haben, aber ich werde mich für ngx-translate entscheiden , da es das asynchrone Laden der Übersetzungsschlüssel unterstützt.
Die Fabrik von i18n-polyfill für den Anbieter TRANSLATIONS scheint nur das synchrone Rohladen eines bekannten festen Gebietsschemas vor dem Bootstrap zu unterstützen.

// sync loading
return require(`raw-loader!../locale/messages.${locale}.xlf`);
// @ngx-translate/i18n-polyfill/esm5/ngx-translate-i18n-polyfill.js
Tokenizer.prototype._advance = function () {
    //...
    this._index++;
    // "this._input" needs to be a string and can't handle a Promise or an Observable
    this._peek = this._index >= this._length ? $EOF : this._input.charCodeAt(this._index);
    this._nextPeek = this._index + 1 >= this._length ? $EOF : this._input.charCodeAt(this._index + 1);
}

@ocombe wie nah ist das Polyfill, das Sie geschrieben haben, an dem, was veröffentlicht wird? Gibt es etwas, dessen wir uns bewusst sein oder auf das wir uns vorbereiten sollten? Würde es Ihnen etwas ausmachen, eine Liste der Funktionen mit i18n aufzulisten, die in Version 6 veröffentlicht werden, und wie das Testen mit i18n läuft?

Ich habe noch keine weiteren Details zum Codeübersetzungsdienst, wir werden wahrscheinlich nächste Woche daran arbeiten (ich reise nach Mountain View). Ich weiß nur, dass es hinter den Kulissen goog.getMsg aus der Closure-Bibliothek ähnlich sein wird (da es das ist, was Google derzeit intern verwendet): https://github.com/google/closure-library /blob/db9bc1a2e71d4b6ee8f57eebe37eb0c6494e9d7e/closure/goog/base.js#L2379 -L2387 was auch meinem Polyfill ähnelt.

In v6 werden wir Laufzeit-i18n veröffentlichen: ein Bündel für alle Gebietsschemata, Übersetzungen, die zur Laufzeit aufgelöst werden, und vielleicht Code-Übersetzungen, wenn wir die Zeit haben (ansonsten kommt es bald danach). All dies wird hinter einer Flagge stehen, da es die Verwendung des neuen Renderers (namens ng-ivy) erfordert, der nicht kampferprobt sein wird.

Vielen Dank! @ocombe ... das klingt wirklich schön!
Wird es Breaking Changes in der Syntax für die Vorlagenübersetzung geben? Ich denke darüber nach, Übersetzungen zu unserem Projekt hinzuzufügen - möchte es aber nicht in ein paar Wochen komplett wiederholen.

Nein, die Vorlagensyntax ist dieselbe

Danke @ocombe für die tollen Neuigkeiten, das ist sehr vielversprechend. Welche Art von Produktionsreife können wir vom ng-ivy-Renderer erwarten, der mit v6 veröffentlicht wird? Ich verstehe, dass es nicht kampferprobt sein wird, aber es wäre immer noch bereit für den produktiven Einsatz und würde auf allen wichtigen, fast aktuellen Browserversionen funktionieren, richtig?

Sie können den Fortschritt hier verfolgen: https://github.com/angular/angular/issues/21706
Ich glaube nicht, dass alles für v6 bereit sein wird, da es unter einer Flagge steht, werden wir auch nach der Veröffentlichung von v6 weiter daran arbeiten (es ist keine bahnbrechende Änderung oder so).
Ehrlich gesagt bin ich mir nicht sicher, was all diese Dinge sind :D
Ich weiß, dass eine Hello-World-App aus dem CLI bereits funktioniert.
Ich denke, dass einige dieser Dinge erforderlich sind, um von den Optimierungen des neuen Renderers zu profitieren, aber es kann wahrscheinlich funktionieren, ohne dass alles überprüft wird
Davon abgesehen bedeutet dies auch, dass es noch nicht produktionsreif sein wird, wetten Sie Ihr Produkt noch nicht darauf. Es wird nicht auf internen Google-Apps getestet, und wir müssen möglicherweise einige wichtige Änderungen vornehmen, um Probleme zu beheben. Die Verwendung des neuen Renderers erfolgt nach eigenem Ermessen und auf eigenes Risiko

Ist irgendetwas davon in v6-beta4 vorhanden?

Nein, ist es nicht. Überprüfen Sie diese Roadmap , diese Funktion wird von der i18n-Laufzeit blockiert.

aktualisiert @ocombe ?

Der erste PR für Runtime i18n wurde in Master zusammengeführt, zusammen mit einer Hello-World-Demo-App, mit der wir die Funktionen testen werden. Es funktioniert zur Laufzeit und unterstützt theoretisch Codeübersetzungen, auch wenn es noch keinen Dienst dafür gibt.
Im Moment ist es sehr minimale Unterstützung (statische Zeichenfolgen), wir arbeiten daran, neue Funktionen hinzuzufügen (ich werde die Extraktion nächste Woche zum Laufen bringen, und dann dynamische Zeichenfolgen mit Platzhaltern und Variablen).
Danach übernehmen wir den Service für Codeübersetzungen.
Sobald ein neues Feature fertig ist, wird es in Master gemerged, Sie müssen nicht auf einen neuen Major warten.

@ocombe i heart i18n-Funktionen sollten bereits in v4.3 vorhanden sein !! So viele Releases, aber nichts auf i18n. Kann der Teammanager von Angle mehr Arbeiten/Entwickler darauf verteilen? Ich kann Sie alleine verstehen oder zwei Entwickler können nicht schnell vorankommen. Diese i 18n-Funktion ist die unverzichtbare Funktion, um vorzugeben, dass Angle eine Business-App / große App mit schnellem Build ist Diese beiden Funktionen sind die wichtigsten für große Apps, finden Sie nicht? Danke

Ich denke, das einzige, was wir @ocombe sagen können, ist, ihm für all die Mühe zu danken, die er in dieses Feature steckt. Ich bin sicher, wenn es keine Entwickler mehr gibt, liegt das nicht daran, dass er nicht danach gefragt hat. Lass ihn einfach machen, ich bin sicher, wir werden es nicht bereuen, wenn es veröffentlicht wird.

Nur als Referenz...

Ich habe ein alternatives Tool zum Importieren und Exportieren von Zeichenfolgen, das ursprünglich für die Verwendung mit Aurelia entwickelt wurde und Unterstützung für in json -Dateien gespeicherte Zeichenfolgen enthält - es ist ziemlich praktisch, da Webpack es Ihnen ermöglicht, json direkt zu importieren ts Dateien, was Ihrem Code einfachen Zugriff auf diese Strings ermöglicht.

Dieses Tool funktioniert auch mit Angular-Vorlagen und hat eine Reihe weiterer praktischer Funktionen - verwenden Sie es, wenn Sie möchten, oder leihen Sie sich Ideen aus, um die Angular-Tools zu verbessern. Es gibt auch einen darauf basierenden Webpack-Loader - siehe Link in der Dokumentation.

https://www.npmjs.com/package/gulp-translate

Wir haben ein einfacheres Problem und ich bin mir nicht sicher, ob wir das kommende Feature (oder das Polyfill von @ocombe) brauchen.

Wir definieren die Struktur aller reaktiven Formulare mit Konstanten, in denen wir die Eigenschaften jedes Formularelements festlegen. Zum Beispiel:

loginForm = [
  {
    type: 'email',
    placeholder: 'EMAILPLACEHOLDER' // "Your email"
  },
  {
    type: 'password,
    placeholder: 'PASSWORDPLACEHOLDER' // "Your password"
  }
];

Derzeit verwenden wir ngx-translate , also übersetzen wir in der Vorlage Strings wie folgt:

<input *ngFor="let ele of loginForm" [type]="ele.type" [placeholder]="ele.placeholder | translate">

Wir möchten nun auf Angular i18n migrieren. Da sich jedoch nicht alle unsere Strings in einem Template befinden, können wir Angular i18n anscheinend nicht standardmäßig verwenden.

Unsere Situation sieht jedoch einfacher aus als die, in der Übersetzungen zur Laufzeit abgerufen werden müssen. Alle unsere Texte sind in Konstanten vordefiniert und könnten zur Kompilierzeit ersetzt werden, so wie es x18n derzeit für Zeichenfolgen in Vorlagen tut.

Zum Beispiel könnten wir eine komplexere Zeichenfolge wie die folgende haben

placeholder: 'I18N:description|meaning@<strong i="16">@PASSWORDPLACEHOLDER</strong>:Your password'

Zur Kompilierzeit könnte die Zeichenfolge ersetzt werden durch:

placeholder: 'Your password'

Ist dies etwas, das für die Implementierung in Betracht gezogen werden könnte?

Sie könnten das definitiv mit Runtime i18n tun, Sie könnten zum Beispiel den neuen i18n-Dienst in einer Pipe verwenden, um Ihre Platzhalter in ihre Übersetzungen umzuwandeln

Ich stelle fest, dass dieser Thread schon seit einiger Zeit geöffnet wurde, er zeigt das große Interesse an der Entwicklung mehrsprachiger Websites in Angular auf einfache Weise, wobei sowohl HTML- als auch Komponentencode-Texte genau behandelt werden.
ocombe, vergessen Sie bitte nicht, allen Abonnenten eine Benachrichtigung zu senden, wenn dies geschehen wird - ich habe gehört, dass es bis Mai 2018 um die Ecke ist. Und danke für Ihre freundlichen Beiträge!

@ocombe sollen wir Ivy verwenden, um diese Laufzeitdienste nutzen zu können, oder funktioniert es auch mit der alten Engine?

Es wird nur mit Efeu sein, den Sie vorerst nicht verwenden können, da es noch nicht fertig ist

Danke für all deine harte Arbeit @ocombe !

Irgendwelche Informationen darüber, wie schnell wir diese neuen Funktionen nutzen können?

Ivy kann jetzt in Angle 6 mit einem Compiler-Flag in einem Vorabversionszustand aktiviert werden. Können diese neuen 18n-Funktionen derzeit mit der Ivy-Vorabversion verwendet werden?

Noch nicht, aber ich mache gute Fortschritte (ich arbeite gerade Vollzeit daran). Ich werde hier ein Update posten, sobald es in Master zum Testen verfügbar ist

vielen Dank @ocombe ! So viele Menschen profitieren von Ihrer harten Arbeit. Wir alle wissen das sehr zu schätzen!

@ocombe Sind statische Übersetzungen in ts noch geplant? Ich meine das Ersetzen von Ausdrücken zur Kompilierzeit, wahrscheinlich mit Typoskript-Transformation.
Wenn nicht, können wir benutzerdefinierte ts-Transformationen in die ng build -Pipeline einfügen, ohne sie zu extrahieren?

Ich bin mir nicht sicher, ob ich dir folgen kann, was du meinst @TinyMan ? Du meinst, Übersetzungen zur Erstellungszeit zusammenführen zu können (wie es jetzt der Fall ist) oder Übersetzungen in ts-Code verwenden zu können (neben Vorlagenübersetzungen, die wir bereits haben)?

@ocombe Ich meine, die Übersetzung in ts verwenden zu können, aber nicht über einen Dienst oder eine DI- / Laufzeitübersetzung. Ich meine die Übersetzung zur Kompilierzeit, aber für Typoskript. Wie C-Präprozessor. Ich dachte, das wäre laut vicb-Kommentar geplant:

  • Wir können auch statische Übersetzungen unterstützen, wie wir es heute für Vorlagen tun - Zeichenfolgen würden zur Kompilierzeit ersetzt, bessere Leistung, aber eine Version der App pro Gebietsschema,

Ich möchte zum Beispiel schreiben können:

export const Notifications = {
    newComment: i18n("New comment notification@@newComment", "New comment on your story !"),
    newStory: i18n("New story notification@@newStory", "{{0}} wrote a new story !"),
}

Und dann wird dies in etwas wie (in fr) transpiliert:

export const Notifications = {
    newComment: "Un nouveau commentaire a été ajouté a votre article !",
    newStory: "{{0}} a écrit un nouvel article !",
}

Derzeit verwende ich zu diesem Zweck ngx-translate mit einem benutzerdefinierten Marker für die Extraktion (in diesem Beispiel i18n ), und wenn ich die Nachricht anzeigen muss, muss ich this.translate.instant(Notifications.newStory, ["TinyMan"]) anrufen, das die Übersetzung durchführt + die Interpolation. Was ich meine ist, dass wir in der Lage sein müssten, Notifications.newComment zu schreiben, ohne den Übersetzungsdienst aufzurufen. Und für die Zeichenfolgeninterpolation könnten wir eine Interpolationsmethode haben, die nur die ICU und die Interpolation durchführt (die Vorlagenzeichenfolge wäre bereits übersetzt).

Notification.newStory // {{0}} a écrit un nouvel article, static string, no runtime translation
template(Notification.newStory, "TinyMan") // TinyMan a écrit un nouvel article !

Hier werden wir nur die Übersetzungs-HTTP-Anfrage und den Service-Overhead los.

Ich hoffe es klärt auf?

Was Sie beschreiben, steht tatsächlich auf der Roadmap für i18n.
Im Moment wird https://github.com/ngx-translate/i18n-polyfill die Arbeit erledigen.

@TinyMan Ich bin mir noch nicht sicher, ob es über einen Dienst oder eine globale Funktion geht. Beides ist möglich, aber ein Dienst hat auch viele Vorteile: Sie können ihn für Tests verspotten oder durch Ihren eigenen ersetzen, Sie können auch sein Verhalten für jedes Modul / jede Komponente ändern
Ich weiß, dass Google intern Closure i18n (über goog.getMsg ) verwenden wird, was eine globale Funktion ist, und die Funktion wird höchstwahrscheinlich während der Kompilierung basierend auf einem globalen Flag durch den Dienst ersetzt. Ich werde versuchen zu sehen, ob dieses Flag auch extern verwendet werden kann, aber ich sehe nicht, warum nicht. Aber wenn Sie das verwenden, wird es für Vorlagen und Codeübersetzungen verwendet

@ocombe Ich möchte auch hier meinen Dank aussprechen. Ich weiß Ihre Arbeit sehr zu schätzen, die für mich bei meiner Arbeit unglaublich hilfreich sein wird. Eine Frage: Gibt es eine Möglichkeit oder _wird_ es eine Möglichkeit geben, eine AOT-Kompilierung durchzuführen, die nur einen Satz von Bundle-Dateien erstellt, die bei der Suche nach Text zur Laufzeit auf xlf verweisen, um die richtige Zeichenfolge zu erhalten?

Im Wesentlichen benötigen Sie also 1 xlf-Datei pro Sprache plus die 5 oder 6 Bundle-Dateien. Wenn wir jetzt 10 Sprachen haben und die AOT-Kompilierung über 50 Dateien enthält: eine Reihe von Bundle-Dateien pro Sprache ...

Ich kenne den Aufwand oder die Komplexität von so etwas nicht, aber es wäre schön, eine ot-Kompilierung zu haben, aber mit nur 1 Satz Dateien.

ja, das werden wir mit ivy machen, Laufzeit i18n
Bündeln Sie Ihre App einmal und laden Sie die Übersetzungen zur Laufzeit (Sie können die Übersetzungen faul laden)

@ocombe das. ist. unglaublich.

Das macht mich so unglaublich glücklich. DANKE!

Ohne die Fähigkeit, externe Vorlagen zu übersetzen, ist die i18n -Funktion für mich völlig nutzlos.

@ocombe Hallo Olivier!
Irgendwelche Updates?

Danke!

Wenn es fertig ist, spielt es keine Rolle, da wir warten müssen, bis Ivy fertig ist, was für Angular 7 (September/Oktober 2018) geplant ist.

Mit Angular 7 wird diese Ausgabe zwei Jahre alt sein LOL.
Auf jeden Fall war Ivy die Sache, die dieses neue Feature am meisten verzögert hat ...

@ocombe , das freut mich zu hören. Wir stecken derzeit fest und verwenden nur aus diesem Grund einen alten i18n-Dienst, den wir von Grund auf neu eingeführt haben. Da dies in JS nicht möglich ist, ist es extrem schwierig, einige einfache Dinge für uns zu tun:

  • Dynamische Komponenten
  • Integration mit Diensten von Drittanbietern, bei denen wir lokalisierten Text bereitstellen müssen
  • Dynamische Bestätigungsmodalitäten werden angezeigt
  • Unsere API gibt den Fehler types zurück. In unserem Kontext müssen wir diese Fehler dynamisch lokalisieren, und ein vorlagengesteuerter Ansatz wäre klobig.
  • Wir möchten TitleService verwenden, wie das Angular-Team vorschlägt, aber es gibt keine Möglichkeit, lokalisierten Text bereitzustellen!

Ich bin gespannt, wie das Angular-Team derzeit damit umgeht ...

Hallo @vincentjames501 ,
In unserer Firma haben wir versucht, dasselbe zu tun, was Sie jetzt tun, aber es war sehr mühsam, also haben wir schließlich das zuvor in diesem Thread erwähnte i18n-Polyfill verwendet, und bisher funktioniert es großartig.
Der einzige Nachteil, den wir haben, ist die Größe der Bundles unserer App. Wir haben drei Übersetzungsdateien, und jedes Bundle enthält alle darin (wir haben keine Möglichkeit gefunden, das Bundle nur mit der verwendeten Übersetzung zu generieren). Aber all dies sind nur Ärgernisse, von denen wir hoffen, dass sie gelöst werden, wenn Ivy draußen ist.
Prost,

Ich habe eine Übersetzungszuordnung eingefügt und sie in die Datei „environment.ts“ jeder Sprache erneut exportiert. Es funktioniert ohne Probleme, ist nicht in allen Bundles enthalten und benötigt keine externe Bibliothek. Das einzige Problem, das ich habe, ist, dass ich nicht für alle Sprachen denselben Servicemitarbeiter haben kann, da jede Site anders ist, und wenn jemand die Sprache wechselt, kann meine Site nicht erkennen, ob er bereits für Push-Benachrichtigungen registriert ist oder nicht ...

@ocombe irgendwelche Neuigkeiten in Winkel 6?

In Angular v6 wird es nicht sein, wie oben erklärt. Wir sind auf Ivy angewiesen, das für v7 geplant ist.

@ocombe darf ich vorschlagen, dass Sie diesen Thread sperren, damit nur das Team gegebenenfalls sinnvolle Updates geben kann und wir die sich wiederholenden Fragen vermeiden, die Sie ständig beantworten?

Mein Hack zur Verwendung mit dem aktuellen Angular verwendet ein ng-template und erstellt die eingebettete Ansicht programmgesteuert:

<ng-template #messagetotranslate i18n>This message should be translated</ng-template>

und dann in die ts-Datei der Komponente:

@ViewChild('messagetotranslate') messagetotranslate: TemplateRef<any>;

createTranslatedMessage(): string {
  return this.messagetotranslate.createEmbeddedView({}).rootNodes[0].textContent;
}

Die Methode createTranslatedMessage gibt die übersetzte Nachricht zurück. Obwohl ich die Vorlage verwende, um die Nachricht zu deklarieren, die nicht optimal ist, ermöglicht dies dem CLI-Übersetzungstool, sie in den xlf-Dateien zu registrieren, und ich habe eine Möglichkeit, die übersetzte Nachricht programmgesteuert zur Verwendung außerhalb von Vorlagen abzurufen.

Hoffentlich funktioniert die API auch für die Routen! Zum Beispiel

export const routes: Routes = [
 {
  path: '',
  component: HomeComponent,
  data: {
   title: i18n('Home'),
   breadcrumb: i18n('Home')
  }
 }
]

Wenn diese Funktion veröffentlicht wird, würde es eine signifikante Änderung gegenüber der aktuellen i18n-API geben? Würden Sie mir empfehlen, mein Projekt jetzt mit i18n zu starten, oder sollte ich auf die neue i18n-API warten, wenn Angular 7 veröffentlicht wird?

Irgendein Update Wann werden wir Laufzeit- und dynamische Übersetzungsunterstützung bekommen?

Laufzeitübersetzungen sind fertig und zusammengeführt (mit ivy), aber die Compilerseite ist noch nicht fertig.
Ich arbeite gerade an ICU-Ausdrücken.
Ich habe noch nicht begonnen, die dynamischen Übersetzungen zu codieren (Service), aber es ist wahrscheinlich das nächste, was ich nach den ICU-Ausdrücken tun werde.

@vincentjames501 Können wir i18n-Polyfills mit ICU-Ausdruck verwenden? Ich habe keine Lösung, wie ich das implementieren soll

@ocombe , können Sie bitte den Unterschied zwischen Laufzeit- und dynamischen Übersetzungen erläutern?

Es gibt wahrscheinlich keine offizielle Bezeichnung, aber so wie ich es sehe, ist es:

  • Laufzeit: Übersetzungen werden zur Laufzeit aufgelöst, d. h. nicht während des Builds (wie wir es derzeit tun). Es gilt für alle Arten von Übersetzungen (Vorlagen oder im Code)
  • dynamisch bedeutet, dass Sie nur zur Laufzeit wissen, was Sie übersetzen möchten, und Sie dies zur Build-Zeit nicht tun könnten. Dies gilt hauptsächlich für "In-Code"-Übersetzungen, die einen Dienst verwenden. Ich denke, Sie könnten ICU-Ausdrücke in dem Sinne als dynamisch betrachten, dass sie von einer Variablen abhängen, aber Sie können immer noch alle möglichen Übersetzungen zur Erstellungszeit berechnen, da die Anzahl der Fälle endlich ist.

Ich habe das Hinzufügen von i18n-Unterstützung zu dem aktuellen Projekt, das wir entwickeln, verschoben, aber wir nähern uns der Veröffentlichung. Haben Sie eine Ahnung, ob dies in Angle 7 endgültig sein wird? Oder sollte ich andere Möglichkeiten zum Hinzufügen von Übersetzungen in Betracht ziehen?

@andrei-tatar i18n funktioniert seit Angular 2 einwandfrei. Die einzigen Nachteile:

  • Keine Codeübersetzungen (dieses Problem) -> Wenn Sie es brauchen, verwenden Sie i18n-polyfill
  • Wenn Sie AOT erstellen (empfohlen), muss die App für jede Sprache separat erstellt werden
  • Da jede App separat erstellt wird, müssen Sie beim Umschalten der Sprache die Seite neu laden

Für die letzten beiden Punkte könnten Sie stattdessen @ngx-translate verwenden. Aber es funktioniert anders als das in Angular eingebaute i18n, sodass ein späteres Update einige Zeit in Anspruch nehmen kann. Für die Polyfill wird das Update im Handumdrehen mit wahrscheinlich keinen Breaking Changes kommen.

@ocombe

Wie wir mit dem bedingten Operator mit der Angular i18n-Funktion umgehen können

[email protected]> schrieb:

@shobhit12345 https://github.com/shobhit12345

Wir verwenden ngSwitch, um alle Nachrichten zu erstellen, damit wir i18n-Tags anhängen können
sie einzeln.

AusblendenShowGeschichte

Wir verwenden diese Methode häufig, um die fehlenden dynamischen Übersetzungen zu umgehen.
Mit ein wenig Nachdenken lässt sich überraschend viel Text ausdrücken
auf diese Weise in Vorlagen. Ein gängiges Muster besteht darin, ein Array von Nachrichten zu haben,
und verwenden Sie dies dann mit ngFor und ngSwitch, um die Nachrichten zu erstellen,
etwas wie das:

ts

Nachrichten = [ 'Dies ist die erste Nachricht', 'Dies ist die zweite Nachricht' ]

html


i18n="@@firstMesssage">Dies ist die erste Nachricht
i18n="@@secondMesssage">Dies ist die zweite Nachricht

Es ist etwas wortreich - aber es funktioniert!


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/angular/angular/issues/11405#issuecomment-415731284 ,
oder den Thread stumm schalten
https://github.com/notifications/unsubscribe-auth/AGwM6jcWIpwtGxhkH1fwnVXNagRxmMnoks5uT-LxgaJpZM4J2pkr
.

Wenn es fertig ist, spielt es keine Rolle, da wir warten müssen, bis Ivy fertig ist, was für Angular 7 (September/Oktober 2018) geplant ist.

Es ist schon Oktober. Glauben Sie, dass wir die neuen Funktionen bis Ende Oktober haben werden?

@lizzymendivil laut https://is-angular-ivy-ready.firebaseapp.com Ivy ist zu 65 % fertig und es scheint unwahrscheinlich, dass es in nur 30 Tagen fertig ist

Ja, Efeu wird nicht in einem Monat fertig sein.

@ocombe kannst du das bitte sperren, damit nur du Updates posten kannst. Es ist ein wenig nervig, all die Benachrichtigungen über all die "Wann ist es fertig?" Bemerkungen

@ocombe es sieht so aus, als ob Ivy jetzt bei etwa 94 % liegt, denkst du, dass dies bis Ende des Jahres fertig sein könnte?

Ich glaube nicht. Feature ready und bug free (= nutzbar) zu sein, ist etwas ganz anderes. Wir arbeiten gerade hauptsächlich daran, Dinge zu reparieren.

@ocombe können wir glauben, dass i18n vor Winkel 8 kam?

Ich glaube nicht. Feature ready und bug free (= nutzbar) zu sein, ist etwas ganz anderes. Wir arbeiten gerade hauptsächlich daran, Dinge zu reparieren.

Ok, danke für die prompte Antwort, sehr zu schätzen.

Irgendein Update @ocombe , dass bis wann wir erwarten sollten (Jahresende sehe ich in den letzten Kommentaren), dass der Teil "Code Translation" zusammen mit "Template Translation" für die I18N-Unterstützung mit Angular verfügbar ist? Wir dachten, ngx-translate-polyfill für dasselbe zusammen mit der Angular I18n-Funktion zu verwenden, aber auch dort scheint es, dass die xlf-Unterstützung nicht verfügbar ist, um vorhandene xlf-Dateien mithilfe von https://github.com/biesbjerg/ngx-translate-extract CLI zusammenzuführen .

Danke !

@Abekonge

Wir verwenden ngSwitch, um alle Nachrichten zu erstellen, sodass wir ihnen individuell i18n-Tags hinzufügen können.
Es ist etwas wortreich - aber es funktioniert!

Danke für den Vorschlag! Es scheint am einfachsten zu verstehen. Meine Frage ist, verwenden Sie diese Implementierung immer noch in Situationen, in denen das Array "viele" Werte hat, z. B. 10 oder mehr? Scheint, als würde der Code sehr sperrig werden.

Ich weiß nicht, ob wir welche mit so vielen haben, aber warum nicht. Wenn die Nachrichten an mehreren Stellen verwendet werden, erstellen wir kleine i18n-Komponenten, die im Grunde nur die Switch- und i18n-Tags sind.

David

Den 23. Jan. 2019 k. 19.24 skrev Andrew Bissada [email protected] :

@Abekonge

Wir verwenden ngSwitch, um alle Nachrichten zu erstellen, sodass wir ihnen individuell i18n-Tags hinzufügen können.
Es ist etwas wortreich - aber es funktioniert!

Danke für den Vorschlag! Es scheint am einfachsten zu verstehen. Meine Frage ist, verwenden Sie diese Implementierung immer noch in Situationen, in denen das Array "viele" Werte hat, z. B. 10 oder mehr? Scheint, als würde der Code sehr sperrig werden.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub an oder schalten Sie den Thread stumm.

So verwenden Sie i18n-polifills in Validator-Klassen. Ich kann keine verdeckte Validierungsnachricht über den i18n-Dienst verwenden.

//Im Bauteil
this.crForm= this.fb.group({
Nutzername: [''],
ePasswort: [''],
}, { Prüfer: neuer AccValidator(this.i18n).validate()}
);

//Validator

import { AbstractControl, ValidationErrors, FormGroup, FormControl } from '@angular/forms';
importiere { I18n } aus '@ngx-translate/i18n-polyfill';
Exportklasse AccValidator{
Konstruktor (i18n:I18n)
{

}
validate() {       
    return (group: FormGroup): createAccountError => {
        if (group) {
            this.i18n("test");
}}}

unten Fehler bekommen

RROR-Fehler: Nicht erfasst (versprochen): TypeError: i18n ist keine Funktion
TypeError: i18n ist keine Funktion
bei FormGroup.eval [als Validator] (acc-validator.ts:9)
bei FormGroup.AbstractControl._runValidator (forms.js:3433)
bei FormGroup.AbstractControl.updateValueAndValidity (forms.js:3387)
bei neuer FormGroup (forms.js:4326)
bei FormBuilder.group (forms.js:7864)

@ocombe

So verwenden Sie i18n-Polyfills mit const in .ts-Dateien

export const glossayModel= () => [
{
Titel: 'Testdaten',
aktiv: wahr,
Daten: [

        [
            {
                title: 'test data',
                data: "test data."
            },
            {
                title: 'test data',
                data: "test data"
            },
            {
                title: 'test data',
                data: "test data"
            },
            {
                title: 'test data',
                data: "test data."
            },
            {
                title: 'Past Due',
                data: "test data."
            }

]]}];


{VAR_SELECT, select, Medical {Medical} Dental {Dental} Medical & Dental {Medical & Dental} Catastrophic & Dental {Catastrophic & Dental} Catastrophic {Catastrophic} }
{VAR_SELECT, select, Medical {Medical} Dental {Dental} Medical### & Dental {Medical y Dental}
Katastrophisch ### & Dental{Katastrophisch y Dental} Katastrophisch {Katastrophisch} }

Wenn ich einen ICU-Ausdruck mit Sonderzeichen verwende, wird er nicht konvertiert.

@ocombe Wie gehe ich mit Breadcrumbs mit i18n-Polyfills um?

Konstante Routen exportieren: Routen = [
{
Weg: '',
Komponente: HomeComponent,
Daten: {
Titel: 'Zuhause',
Breadcrumb: 'Zuhause'
}
}
]

@ocombe

So verwenden Sie i18n-Polyfills mit const in .ts-Dateien

export const glossayModel= () => [
{
Titel: 'Testdaten',
aktiv: wahr,
Daten: [

        [
            {
                title: 'test data',
                data: "test data."
            },
            {
                title: 'test data',
                data: "test data"
            },
            {
                title: 'test data',
                data: "test data"
            },
            {
                title: 'test data',
                data: "test data."
            },
            {
                title: 'Past Due',
                data: "test data."
            }

]]}];

Sie können so verwenden
{
Daten: 'Testdaten',
Titel: this.i18n({ Wert: 'Name', ID: 'Name' }),
}
Injizieren Sie I18n Polyfill in den Komponentenkonstruktor wie folgt
Privat i18n: I18n
Wenn Sie Übersetzungen in ts-Dateien verwenden, müssen Sie ngx-extractor und xliffmerge verwenden, um diese ts-Dateien zu übersetzen. https://www.npmjs.com/package/ngx-i18nsupport

@ JanneHarju
es funktioniert nicht, die Daten werden nicht in der xlf-Datei abgerufen.

Hier ist mein Übersetzungsskript:
"translate-i18n": "ng xi18n --output-path locale && ngx-extractor -i src/**/*.ts projects/**/*.ts -f xlf -o src/locale/messages.xlf && xliffmerge --profile xliffmerge.json fi en",

und hier ist xliffmerge.json

{
  "xliffmergeOptions": {
    "srcDir": "src/locale",
    "genDir": "src/locale",
    "i18nFile": "messages.xlf",
    "defaultLanguage": "en",
    "useSourceAsTarget": true
  }
}

@ JanneHarju
Ja, ich verwende dieselbe Konfiguration und kann .ts-Nachrichten in einer xlf-Datei extrahieren.

Aber const habe ich in verschiedenen .ts-Dateien

export const glossayModel= () => [
{
}

Ich importiere Komponenten, wenn ich versuche, i18n mit const zu verwenden, werden die Werte nicht extrahiert.

Was ist, wenn Sie konstante Werte wie provider.

{
    provide: glossayModel,
    useFactory: () => glossayModel()
}

Code könnte gebrochen sein, aber Sie bekommen vielleicht einen Punkt.

wie man Breadcrumbs übersetzt

Konstante Routen: Routen = [
{
Pfad: './enroll-new.component',
Komponente: EnrollNewComponent,
Daten: {
Breadcrumb: 'Anmeldung'
},
}
]

Können Sie aufhören, diesen Thread als Support-Thread für i18n-polyfill oder andere Probleme zu verwenden? Wenn Sie eine Frage zu i18n-polyfill haben, stellen Sie ein Problem in diesem Repo.
@ocombe vielleicht kannst du dieses Thema sperren? Eigentlich sollte alles Wichtige abgedeckt sein.
Was ist die abgewinkelte Version, die Sie für die Veröffentlichung der in diesem Thema erwähnten i18n-Unterstützung planen?

Ja, vorerst gesperrt.
Wir arbeiten hart daran, Ivy mit v8 als Opt-in-Beta verfügbar zu machen. Runtime i18n wird mit Google Closure (was Google intern verwendet) verwendbar sein, wodurch wir es debuggen können (es ist eine sehr große Änderung). Für alle anderen können Sie ivy mit i18n testen, aber Sie können keine Übersetzungen laden. Die App wird in der Originalsprache ausgeführt, in der die App codiert wurde.
Der Laufzeitdienst, der zur eigentlichen Übersetzung benötigt wird, gibt den Text derzeit unübersetzt zurück. Da wir alle daran arbeiten, Fehler mit dem vorhandenen Code zu beheben, werden neue Funktionen auf die Zeit nach der Veröffentlichung beschränkt sein. Wir werden daran arbeiten, sobald v8 draußen ist, es sollte meine erste Aufgabe sein.
Ich werde ein Update hinzufügen und diesen Thread freischalten, sobald wir Neuigkeiten haben.

Für das, was es wert ist, kann das neue $localize -Tag, an dem wir arbeiten, programmatisch verwendet werden.

Z.B

const name = 'World';
$localize `Hello ${name}:name!`;

Und wird dann in der Lage sein, Übersetzungen für Hello {$name}! bereitzustellen, die zur Kompilierzeit (oder Laufzeit) ersetzt werden können.

Dies ist jetzt verfügbar (falls nicht dokumentiert).

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen