Angular: i18n: Dapat menggunakan string terjemahan di luar template

Dibuat pada 7 Sep 2016  ·  204Komentar  ·  Sumber: angular/angular

Saya mengirimkan ... (centang satu dengan "x")

[x] feature request

Perilaku saat ini
https://github.com/angular/angular/issues/9104#issuecomment -244909246

Saya tidak berpikir itu mungkin, seperti yang saya katakan sebelumnya hanya berfungsi dengan teks statis, itu tidak akan mengurai teks pada kode js, hanya templat

Perilaku yang diharapkan/diinginkan
Mampu menerjemahkan string yang digunakan di mana saja dalam kode, menggunakan API.

Reproduksi masalah

Apa perilaku yang diharapkan?
Saya mereferensikan penggunaan $translate.instant untuk mengekspos kasus penggunaan nyata:

  • Teks yang dirender khusus:
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);

Contoh lainnya:

  • Mendapatkan nama file gambar dari gambar yang diekspor dari laporan yang diberikan HTML:
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;
    }
  • Terkadang Anda menerjemahkan, terkadang menggunakan data model (bisa sangat bertele-tele dalam template):
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', '');
        }
    }
  • Menggunakan plugin bagan pihak ketiga (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')
                    }
                }
            }
        });
  • Untuk mengatur variabel konfigurasi dan merender teks tanpa pipa karena tidak selalu berupa string yang diterjemahkan
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')
        };
  • Untuk mengatur window.title :) :
SetWindowTitle(title:string) {
        if (!!title) {
            this.$window.document.title = this.$translate.instant(title);
        }
    }
  • Pemformatan tanggal khusus:
dateHuman(date:Date):string {
        return date.getDate() + ' ' + this.$translate.instant('GLOBAL_CALENDAR_MONTH_' + date.getMonth())
            + ' ' + date.getFullYear();
    }
  • Urutkan hal-hal berdasarkan nilai yang diterjemahkan:
// 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();
        });
    }
  • Ekspor data mentah ke CSV atau Excel dengan nilai yang diterjemahkan:
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;
    }
  • Setel string konfigurasi ke plugin pihak ketiga:
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')
                ]
            }
        });
    }


Apa motivasi / kasus penggunaan untuk mengubah perilaku?
Mampu menerjemahkan string di luar template.

Tolong beritahu kami tentang lingkungan Anda:

  • Versi sudut: 2.0.0-rc.6
  • Peramban: [semua]
  • Bahasa: [TypeScript 2.0.2 | ES5 | SistemJS]

@vicb

i18n feature high

Komentar yang paling membantu

Saya pikir ini adalah showstopper nyata, i18n belum siap digunakan sampai ini diimplementasikan.
Misalnya saya tidak dapat mengatur pesan validasi yang diterjemahkan dalam kode

Semua 204 komentar

Saya pikir ini adalah showstopper nyata, i18n belum siap digunakan sampai ini diimplementasikan.
Misalnya saya tidak dapat mengatur pesan validasi yang diterjemahkan dalam kode

@ Mattes83 Apakah Anda mencoba cara ini?

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

:confused: Dokumentasi memberi tahu Anda betapa menyenangkannya memiliki pesan kesalahan dalam kode dan dukungan terjemahan memerlukan apa pun dalam template. Sepertinya ada lebih banyak kebutuhan untuk komunikasi.

@marcalj Saya tahu cara ini ... tapi saya harus memiliki string yang dilokalkan di file ts saya.
@manklu saya sangat setuju

Saya pikir ini adalah showstopper nyata, i18n belum siap digunakan sampai ini diimplementasikan.
Misalnya saya tidak dapat mengatur pesan validasi yang diterjemahkan dalam kode

Ya sama di sini, saya baru saja beralih dari ng2-translate ke Angular2 i18n karena saya lebih suka menggunakan modul OOTB, dan jauh lebih mudah untuk mengekstrak terjemahan (ng2-translate lebih memakan waktu IMO)
Pada tahap ini saya tidak dapat menerjemahkan pesan kesalahan yang muncul dari layanan saya. Tidak ada solusi juga.

Jika seseorang ingin memulai spesifikasi desain, itu akan sangat membantu (yaitu di Google Documents).

Itu perlu membuat daftar semua kasus. Dengan cepat memikirkannya, saya melihat kebutuhan untuk

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

Hai teman-teman, permintaan fitur yang bagus :+1:

Apakah ada solusi yang disarankan untuk menerjemahkan teks *.ts?

@fbobbio Apa yang saya lakukan adalah membuat elemen tersembunyi di template, mis.
<span class="translation" #trans-foo i18n>foo</span> .

Ikat mereka menggunakan:
@ViewChild('trans-foo) transFoo : ElementRef; .

Kemudian ambil nilai yang diterjemahkan
transFoo.nativeElement.textContent .

Terlihat terbelakang, tetapi bekerja untuk kebutuhan saya.

Karena ng-xi18n sudah memproses seluruh kode TS, mengapa tidak menerapkan dekorator seperti @i18n() untuk properti (string-)? Ini kemudian dapat diisi dengan nilai yang diterjemahkan, seperti @Input() digunakan dengan pengikatan data satu arah.
Jika nilai yang tidak diterjemahkan tidak dapat dengan mudah diekstraksi dari kode, letakkan saja dalam argumen seperti ini:

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

dan masukkan sumber ke dalam properti ketika tidak ada target terjemahan.

Ini adalah item penting dalam seluruh siklus internasionalisasi, IMO.

Di toko saya, kami terbiasa dengan alat "ng-xi18n - like" (ekstensi ke xgettext) yang merayapi semua jenis file sumber mencari teks yang ditandai untuk dimasukkan ke dalam file kamus untuk penerjemah.

Saya menyukai markup i18n yang bersih dan mudah di templat HTML, dan saya mengharapkan hal yang sama untuk kode TypeScript.

@vicb Selain kasus penggunaan Anda, saya sedang memikirkan kemungkinan untuk mendukung lokalisasi string yang diinterpolasi dalam kode TS. Namun kemungkinan diperlukan untuk menulis ulang kode TS untuk mendukung skenario seperti itu. Apakah ini akan menjadi pendekatan yang valid?

Ini adalah fitur utama yang menghentikan kami dari menggunakan pendekatan out-of-the-box untuk terjemahan penawaran Angular 2. Kami memiliki banyak komponen berbasis metadata yang kuncinya berasal dari beberapa metadata yang tidak disimpan dalam HTML. Jika kami dapat menerjemahkan melalui pipa atau secara terprogram terhadap TRANSLATIONS yang tersedia, kami dapat membuat komponen ini menunjukkan string yang tepat.

Sementara itu, kami terbatas pada sesuatu seperti ng-translate karena keterbatasan ini.

Cara saya mengatasi masalah ini adalah dengan menambahkan objek 'lang' kosong di layanan yang digunakan di seluruh aplikasi saya. Saya kemudian menerapkan arahan yang membaca semua rentang dalam div dan menyimpan nilai dalam objek itu. Saya menempatkan semua string saya di templat di bagian bawah halaman dengan properti tersembunyi. String kemudian dapat dijangkau dari template atau komponen. Itu jelek dan Anda dapat dengan mudah menimpa entri dengan id yang sama. Tapi itu lebih baik daripada tidak sama sekali.

MELAYANI

@Injectable()
export class AppService {

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

PENGARAHAN

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

TEMPLAT

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

Halo @lvlbmeunier

Terima kasih telah memberikan saran ini untuk solusi sementara kami menunggu implementasi resmi. Saya mencoba menerapkan solusi Anda tetapi sepertinya saya tidak bisa mendapatkan kunci terjemahan dinamis untuk dikenali. Saya mencoba melakukannya seperti ini:

<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>

Kunci baru itu tidak muncul di file xliff saya. Apakah mungkin untuk mencapai ini dengan solusi Anda?

Saya tidak pernah mencobanya tetapi saya hampir yakin bahwa build file xliff tidak menjalankan kode. Memiliki nilai dinamis di i18n akan bertentangan dengan konsep tersebut. Jika Anda mengetahui dengan pasti semua nama yang akan ada dalam daftar Anda, mereka semua harus dideklarasikan secara independen dan bukan dalam perulangan for.

Menambahkan kunci secara manual berfungsi tetapi tidak praktis. Dalam kasus saya, saya mendapatkan ratusan kunci teks yang membutuhkan terjemahan dari API.

Anda dapat menjalankan kode Anda dan mengambil sumbernya dan menyalinnya ke file. Pembuatan file x18n didasarkan pada file statis.

Dengan 4.0.0-beta Anda dapat menetapkan id ke i18n , misalnya mainTitle:

<span i18n="title@@mainTitle">

Dengan ini kami dapat, setidaknya untuk kompiler JIT, membuat Komponen tiruan (tidak perlu ditambahkan ke html aplikasi, cukup modul aplikasi) dengan semua terjemahan "ekstra" kami.

Sebagai permulaan, kami akan menambahkan penyedia tidak hanya ke kompiler tetapi juga ke modul aplikasi:

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

Kemudian kita akan membuat komponen dummy untuk menampung terjemahan tambahan kita, jangan lupa untuk menambahkan komponen ke declarations dari AppModule . Ini agar ng-xi18n dapat menemukan html (menurut saya) dan menambahkannya ke file terjemahan.

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

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

Tambahkan terjemahan kami ke tmp.i18n.html :

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

Sekarang kita dapat membuat layanan di mana kita dapat mengambil terjemahan kita:

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

Sekarang kita dapat melakukan sesuatu seperti:

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

Ini adalah solusi peretasan. Tapi setidaknya kita bisa memanfaatkan file terjemahan, mendapatkan kunci, interpolasi dan tidak harus memiliki html tersembunyi di aplikasi kita.

CATATAN: paket @angular/compiler-cli NPM saat ini dari 4.0.0-beta memiliki versi ketergantungan @angular/tsc-wrapped yang salah. Ini menunjuk ke 0.4.2 seharusnya 0.5.0. @vicb apakah ini mudah diperbaiki? Atau haruskah kita menunggu rilis berikutnya?

@fredrikredflag Luar biasa! Dan bagaimana dengan AOT?

@ghidoz AOT adalah cerita lain. Apa yang ingin kami lakukan adalah mengkompilasi semua terjemahan sehingga kami bisa mendapatkannya dengan kunci. Tetapi karena ngc akan menggantikan semua i18n dengan terjemahan yang benar, kami tidak dapat memanfaatkannya. Tidak dapat menemukan opsi/properti terbuka yang berisi terjemahan yang diuraikan dari ngc . Kita dapat menggunakan pendekatan dinamis yang sama seperti untuk JIT dengan mengambil file xlt dengan cara itu masih menyediakannya di token TRANSLATION . Namun ini bertentangan dengan tujuan AOT.

JANGAN LAKUKANNYA UNTUK APLIKASI PRODUKSI APAPUN .

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

Pemikiran saat ini tentang bagaimana menerapkan ini:

@Component()
class MyComp {
  // description, meaning and id are constants
  monday = __('Monday', {description?, meaning?, id?});
}
  • karena kami tidak dapat memengaruhi struktur DOM dengan konstruksi seperti itu, kami dapat mendukung terjemahan runtime - akan ada satu versi biner dan resolusi akan terjadi saat runtime,
  • kami juga dapat mendukung terjemahan statis seperti yang kami lakukan hari ini untuk templat - string akan diganti pada waktu kompilasi, kinerja yang lebih baik tetapi satu versi aplikasi per lokal,
  • kami mungkin dapat mendukung __(...) dalam template di lain waktu,
  • ini akan diimplementasikan melalui trafo TS yang tersedia dari 2.3 - kita mungkin bisa memiliki prototipe sebelumnya.

/cc @ocombe

Saya kira __() adalah untuk metode yang belum memiliki nama (dan metodenya tidak akan benar-benar menjadi __ , kan?)

Ini adalah ide bagus untuk terjemahan statis yang mungkin Anda gunakan di kelas Anda, dan menurut saya cukup sederhana untuk diterapkan.

Bukan __() itu namanya, apa kamu tidak suka :)

Ini biasanya digunakan dalam kerangka terjemahan - tetapi Anda akan dapat import {__ as olivier} from '@angular/core' jika Anda lebih suka nama lain!

eeeeeeh itu tidak terlalu menjelaskan diri sendiri :D
Sepertinya fungsi yang sangat pribadi

Saya juga tidak suka nama metode ___ :) Saya membayangkan itu akan menjadi layanan?
Either way, senang melihat kemajuan 👍

Saya suka __()! :D Sangat gettext-y dan pendek.

Di dunia JS, saya hanya memiliki pengalaman dengan @ocombes ng2-translate, di mana menandai semua teks dengan this._translateService.instant() membuat kode agak sulit dibaca dibandingkan dengan alternatif yang lebih pendek, seperti yang diusulkan di sini.

tidak ada yang menghentikan Anda untuk mengganti nama layanan terjemahan ng2 __ lho :)

Sebenarnya, saya tidak tahu cara membungkus metode layanan DI dalam fungsi sederhana - lagi pula, tidak apa-apa, itu di luar cakupan masalah ini :-) Komentar saya hanya +1 untuk menggunakan __ seperti yang diketahui jika Anda' pernah menggunakan framework terjemahan lain, setidaknya di dunia PHP.

oke, mungkin ___ baik-baik saja, lebih baik daripada "this.translationService.getTranslation()", jauh lebih pendek.
Dan ya Anda dapat mengganti namanya jika Anda mau.

Bagaimana dengan i18n(...) bukannya __(...) ?

Tolong hentikan perdebatan tentang nama, bukan itu intinya. Terima kasih.

@vicb dengan monday = __('Monday', {description: 'First day of the week', id: 'firstDatOfWeek'}); apakah mungkin untuk menyelesaikannya dengan id, yaitu:

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

Juga apakah Monday menjadi lokal untuk kelas yang ditentukan atau apakah mungkin untuk diselesaikan dari mana saja? Saya sedang memikirkan terjemahan umum seperti "tutup", "buka", dll.

Saya bertanya-tanya apa solusi terbaik saat ini yang Anda rekomendasikan untuk digunakan dengan AOT hingga rilis resmi mendukungnya?

Salam,
Sean

Wastafel dapur sudut 2: http://ng2.javascriptninja.io
dan source@ https://github.com/born2net/Angular-kitchen-sink

@vicb ada berita, di sana ^

Sampai fitur ini diimplementasikan, saya menggunakan fitur terjemahan atribut .

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

Dari templat komponen induk:

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

Ini adalah solusi, tapi tetap saja, saya pikir itu yang terbersih sejauh ini. Ini memberi Anda akses ke title yang diterjemahkan dalam ts .

Saya mulai mengerjakan fitur ini, mengharapkan dokumen desain segera :-)

ini akan menjadi fitur yang paling dinanti

Itu kabar baik. Terima kasih @ocombe .

Dokumen desain tersedia di sini: https://goo.gl/jQ6tQf
Setiap umpan balik dihargai, terima kasih.

manis, akan membaca secepatnya!

Terima kasih @ocombe

Saya sudah membaca dokumennya. Ringkasan yang indah.

Mampu mengekstrak string dari file ts terdengar luar biasa.

Saya tidak yakin kapan peningkatan TypeScript akan tersedia untuk Angular4.

Artinya fitur ini yang seharusnya sudah tersedia selama berbulan-bulan karena hampir semua orang yang mengalami keterbatasan ini tidak akan dapat menggunakan solusi ini sebelum setidaknya 3/6 bulan lagi.

Saya mungkin bukan satu-satunya saat ini yang menggunakan ngx-translate untuk mengelola terjemahan di pengontrol saya sementara saya mengandalkan angular i18n untuk templat.

Tujuan untuk menggabungkan semuanya menjadi i18n jelas sangat bagus.

Tetapi selain dari penyederhanaan dalam hal pemahaman bagaimana menerapkan i18n dalam kerangka sudut, apakah pendekatan ini benar-benar akan meningkatkan kinerja dibandingkan dengan implementasi ngx-translate saat ini?

Dari pemahaman saya sekarang, satu-satunya bonus adalah dapat mengekstrak string dari pengontrol.

Juga batasan besar saat ini adalah pluralisasi, harap pastikan itu berfungsi dengan baik ketika Anda merilis seluruh peningkatan. Saya telah membaca banyak tiket terkait i18n di mana xliff dan xmb keduanya tidak akan menangani ini dengan benar. Ini adalah satu kasus lagi di mana saya perlu beralih kembali ke ngx-translate untuk memberikan solusi yang berfungsi.

@ocombe Terima kasih atas dokumen desain terperinci, ini sepertinya solusi yang sangat bagus untuk permintaan fitur ini. Desain saat ini membahas kasus penggunaan yang saya coba selesaikan.

Satu pertanyaan: Desain berbicara tentang layanan I18N untuk mode JIT, dan Transformer TS 2.2.x untuk mode AOT. Apakah saya benar dengan mengasumsikan bahwa transformator akan menggantikan panggilan ke metode layanan dengan terjemahan statis, dan juga menghapus semua referensi yang tersisa ke layanan I18N?

@Thommas Angular 4 akan menggunakan TypeScript 2.1 (yang berarti Anda harus memutakhirkan), tetapi Anda sebenarnya sudah dapat menggunakan versi TypeScript yang lebih baru (2.2.1 misalnya) dengan Angular 2 atau 4.

Dalam hal peningkatan kinerja melalui ngx-translate, itu tergantung apakah Anda menggunakan AOT atau tidak. Jika Anda menggunakan AOT maka itu adalah keuntungan, tetapi Anda mungkin tidak akan melihat perbedaannya. Dalam JIT (tanpa AOT) tidak akan ada keuntungan (sebenarnya itu tergantung jika Anda menggunakan get yang dapat diamati atau metode instant sinkron, biaya yang dapat diamati lebih dari sekadar panggilan fungsi sederhana).
Saya berbicara tentang i18n dalam kode Anda di sini. Jika kita berbicara tentang template maka ada keuntungan nyata yang terlihat jika Anda menggunakan Angular i18n (dalam AOT dan JIT) karena tidak menggunakan binding. Semakin banyak terjemahan yang Anda gunakan, semakin banyak yang Anda peroleh.

Saya akan memastikan bahwa pluralisasi bekerja persis sama seperti pada template. Apakah ada masalah sekarang dengan itu di template?

@schmuli satu-satunya waktu Angular dapat mengganti kode Anda adalah ketika Anda menggunakan AOT. Jika tidak, maka panggilan layanan akan tetap sama dalam kode Anda.
Tetapi jika Anda menggunakan AOT maka panggilan layanan akan diganti dengan terjemahan statis (hanya variabel yang mungkin Anda gunakan yang akan tetap dinamis). Saya tidak yakin apakah kami akan menghapus referensi ke layanan I18n, karena referensi tersebut dapat digunakan untuk hal lain di masa mendatang, saya harus melihat apa yang mungkin dengan transformator setelah saya mulai menulis kode. Apakah Anda memikirkan kasus penggunaan di mana ini akan menjadi masalah?

@ocombe Saya tidak dapat memikirkan kasus penggunaan di mana meninggalkan kode akan menjadi masalah, kecuali jika kami mempertimbangkan injeksi DI tambahan yang tidak akan digunakan (apakah ini masalah nyata?).

Mempertimbangkan apa yang Anda tulis bahwa layanan tersebut mungkin digunakan untuk hal-hal lain di masa mendatang, dan potensi kesalahan yang ditimbulkan dengan mengubah kode pengguna, saya akan mengatakan bahwa mungkin lebih baik untuk menghindari penghapusan kode sama sekali.

Mungkin akan berguna untuk menggunakan layanan untuk mendapatkan lokal saat ini di AOT. Pertimbangkan misalnya kasus di mana Anda memiliki server yang dapat mengembalikan teks dalam beberapa bahasa, oleh karena itu Anda memerlukan lokal saat ini untuk disertakan dalam permintaan. Namun Anda selalu dapat menggunakan string terjemahan tiruan sebagai solusi.

@diego0020 Anda sudah bisa mendapatkan lokal, cukup masukkan LOCALE_ID dari inti

@ocombe Pluralisasi tidak diterapkan dengan xliff dan tidak ada seorang pun di luar google yang tahu cara menggunakannya dengan xmb juga. Lihat juga: https://github.com/angular/angular/issues/13780

Bagaimanapun, tidak ada yang menghalangi implementasi i18n kami sekarang ngx-translate dengan pipa pluralisasi akan dilakukan untuk saat ini. Mudah-mudahan semuanya akan terlihat lebih baik di NG4 dan dokumentasi akan mencerminkan perbaikan. Terima kasih.

@Thommas ICU dengan xliff akan segera diperbaiki: https://github.com/angular/angular/pull/15068 dan jika Anda ingin tahu cara menggunakannya, ada di dokumen: https://angular.io/docs/ ts/latest/buku masak/i18n.html#! #kardinalitas

Mohon maaf, Apakah ada ETA? Karena saya dengar itu akan tersedia dalam rilis ng4.0.0 tapi tidak! Terima kasih

Cc @ocombe

Kami masih mengerjakan desainnya, ada banyak hal tak terduga yang perlu dipertimbangkan (seperti bagaimana perpustakaan dapat mengirimkan terjemahan mereka sendiri), ...
Harapkan ini untuk 4.2, tetapi itu tidak dijamin.

ok terima kasih @ocombe , saya punya dua pertanyaan:

  1. Sebenarnya kita bisa menerjemahkan teks dalam template yang menyertakan interpolasi, seperti:
    <span i18n>This is {{myValue}}</span>
  1. Saya bertanya karena sebenarnya saya tidak dapat mengekstrak, saya tidak tahu mengapa saya mendapatkan kesalahan ini:
    Could not mark an element as translatable inside a translatable section

@istiti

  1. ya kamu bisa.
  2. Anda perlu memperhatikan lokasi direktif i18n Anda, itu harus ditempatkan langsung pada elemen yang berisi teks, bukan pada saudara kandung lainnya.
    Misalnya:
    <div i18n><span i18n>my text</span></div> - ini tidak bagus
    <div><span i18n>my text</span></div> - ini bagus

@royiHalp
Terima kasih

  1. Ok bagaimana menerjemahkan dengan interpolasi?
  2. Saat mengekstrak ngc, dapatkan saya file dan baris dan potongan kode tetapi saya tidak memiliki i18n yang dibungkus di dalam i18n lainnya
    Itu sangat sulit untuk menemukan orang tua saya yang mana yang secara tidak sengaja memiliki atribut i18n

@istiti

  1. anda melakukannya seperti elemen lain, cukup tambahkan arahan i18n seperti yang Anda lakukan:
    <span i18n>This is {{myValue}}</span>
    hasilnya dalam file messages.xlf akan menjadi:
    <source>This is <x id="INTERPOLATION"/></source>
    sekarang ketika Anda menerjemahkannya ke lokal yang berbeda Anda harus menempatkan <x id="INTERPOLATION"/> di tempat yang benar dalam kalimat, untuk membantu orang lain memahami maksud Anda, Anda dapat menambahkan deskripsi ke direktif i18n seperti ini:
  1. dari pengalaman saya kesalahan Could not mark an element as translatable inside a translatable section adalah seperti yang saya jelaskan, saya ingat bahwa jika saya membaca kesalahan dengan cermat saya dapat melihat di file mana saya memiliki masalah.

@fredrikredflag Terima kasih banyak!

Kode Anda sangat berguna! Saya hanya perlu memperbaiki satu masalah karena tampaknya xliff.load mengembalikan objek yang berbeda saat ini, jadi this._translations perlu disesuaikan dengan:

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

dan validasi kecil dalam metode get jika kami meminta kunci yang tidak ada:

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

Juga, saya pikir komponen i18n yang kosong adalah pohon yang diguncang atau sesuatu jadi saya harus memasukkan string pada templat komponen yang sesuai dengan:

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

Untungnya saya hanya perlu beberapa string ke miniApp saya sehingga berfungsi dengan baik dalam produksi dengan AoT.
Terima kasih lagi!!!

P/S: alat xliffmerge oleh Martin Roob harus digunakan saat ini, dan TinyTranslator -nya juga B-)

Saya menggunakan kompilasi AoT dan proyek saya mendukung dua bahasa: Inggris dan Rusia. Saya telah menemukan solusi sementara untuk masalah ini dengan menggunakan konfigurasi lingkungan.

Berkas environments/environment.ts berisi:

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

export const environment = {
  production: false
};

export const messages = messagesEn;

Juga ada dua file lain environment.prod-en.ts dan environment.prod-ru.ts dengan konten berikutnya:

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

export const environment = {
  production: true
};

export const messages = messagesEn;

Dan untuk bahasa Rusia:

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

export const environment = {
  production: true
};

export const messages = messagesRu;

Setiap file pesan dapat berisi sesuatu seperti ini:

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

Dalam kode saya (komponen, layanan, dll) saya hanya mengimpor pesan:

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

Dan gunakan mereka:

alert(messages.MessageKey);

Di .angular-cli.json Saya telah menentukan lingkungan produksi berikutnya:

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

Berhasil!

@alex-chuev Sudahkah Anda mencoba ini dengan JIT?

@ocombe ada perkiraan kasar kapan ini akan tersedia?

Fitur hebat btw :)

Itu ditahan sampai perubahan pada kompiler dibuat, jadi bukan untuk 4.2, saya masih berharap untuk membuat ini untuk 4.3

ada yang tahu bagaimana menerapkan i18n dalam nilai param misalnya di [title] dalam contoh berikut:
jadi dengan kata lain, tambahkan terjemahan ke kata HELLO

Salam

Sean

Jika HELLO hanyalah string yang Anda ketikkan ke dalam template HTML, Anda dapat melakukan hal berikut:
```html

````
Dokumentasi memiliki contohnya. Lihat di sini: https://angular.io/docs/ts/latest/cookbook/i18n.html#! #translate-atribut

Jika Anda harus mengikat ke properti string dalam komponen, Anda harus menunggu fitur ini, atau menerapkan cara menerjemahkan khusus (sepengetahuan saya).

@ocombe

Kami masih mengerjakan desainnya, ada banyak hal tak terduga yang perlu dipertimbangkan (seperti bagaimana perpustakaan dapat mengirimkan terjemahan mereka sendiri), ...

Ini sangat penting. Saya harap ini juga merupakan bagian dari fitur ini. Karena saat ini saya tidak melihat bagaimana perpustakaan pihak ketiga dapat menyediakan terjemahan untuk aplikasi Anda. Selama pembuatan, Anda hanya dapat menentukan 1 file XLIFF, dan tampaknya Anda harus membuat pustaka terlebih dahulu agar bahasa Anda memiliki kemampuan untuk menerjemahkannya.

Ya, saya juga menunggu itu! Ini SANGAT penting untuk proyek yang ditujukan untuk audiens yang tidak berbahasa Inggris!

Ini jelas sesuatu yang ingin kami dukung, tim sedang mengerjakan refactoring kompiler yang memungkinkan kami melakukan itu :-)

Ada perkiraan versi mana yang akan dibidik? Saya membaca bahwa mungkin sekitar 4,3?

Karena refactoring (dan melanggar perubahan) yang diperlukan, saya khawatir tidak akan sebelum v5

Whaaaat Oh tidak, saya menunggu fitur ini untuk 4.2 yang Anda katakan dan sekarang untuk v5 ️ Saya berpikir untuk v5 akan menjadi perubahan bahasa yang dinamis tidak merilis fir setiap versi tetapi bagaimanapun berharap itu akan menjadi suatu hari bahkan dengan 36k build yang berbeda untuk masing-masing bahasa. Saya hanya ingin tahu kapan v5? Terima kasih

@ocombe

@istiti saya mengatakan bahwa itu bukan tanggal yang dijamin ;-)
Jadwal rilis ada di sini: https://github.com/angular/angular/blob/master/docs/RELEASE_SCHEDULE.md
Rilis final untuk v5 adalah 2017‑09‑18, tetapi akan ada beta dan RC sebelumnya

Apakah ada perubahan untuk membuat satu file lokal untuk setiap komponen? artinya, buat potongan messages.xlf , misalnya: messages.{component}.{locale}.xlf dan misalnya hanya messages.{component}.xlf untuk bahasa default.

Belum

Kerusakannya sangat minim karena waktu pembuatan @ocombe

Saya bingung... Apakah ini permintaan perubahan / perubahan untuk datang resmi atau tidak?
Memiliki masalah yang sama di sini, terjemahan tidak hanya berlaku untuk template.
Memiliki redux, komponen tampilan pohon khusus dll... semua dihasilkan dari objek javascript DALAM KODE, bukan per template

Ini resmi, dan akan datang tetapi kami harus membuat perubahan mendalam lainnya pada kompiler terlebih dahulu, itulah sebabnya mengapa itu tidak siap untuk 4.3

Apakah sudah diketahui pada versi berapa fitur ini akan tersedia/direncanakan? 4.3.1, 4.3.2 ... 4.3.X ?

Tidak ada lagi versi mayor/minor untuk cabang 4.x (hanya tambalan: https://github.com/angular/angular/blob/master/docs/RELEASE_SCHEDULE.md) yang artinya ini untuk 5.x , tidak yakin yang mana.

Apakah ini masih diharapkan untuk masuk ke 5.x? Saya tidak bisa melihatnya di versi beta. Terima kasih

Mungkin di v50.x bukan v5.x 😂

5.x ya, tapi kemungkinan besar tidak di 5.0

Le jeu. 3 août 2017 12:56, vltr [email protected] a écrit :

Mungkin di v50.x bukan v5.x 😂


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/angular/angular/issues/11405#issuecomment-319936876 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AAQMorXMbyI8l6K3QA4jmXEKawiEC46xks5sUad0gaJpZM4J2pkr
.

Hai @ocombe Saya sangat tertarik dengan proses agar ini berfungsi dan bagaimana dengan cara kerja kompiler saat ini menjadikan ini tugas yang lebih sulit. Apakah Anda memiliki kejelasan seperti apa timeline itu atau apakah ini masih kemungkinan 5.0 tetapi beberapa 5.x?

@arackow kemungkinan besar akan 5.x, @vicb sedang mengerjakan perubahan terakhir pada kompiler yang akhirnya akan memungkinkan ini

@ocombe ... apakah ada dokumen desain yang menjelaskan konsep solusi untuk string di luar templat? Kami berada dalam fase pengembangan proyek di mana akan sangat bagus untuk mengetahuinya, jadi kami akan dapat menyiapkan solusi sementara kami dan kemudian akan jauh lebih mudah untuk beralih ke sintaks Angular akhir.

Kami memiliki dokumen desain tetapi didasarkan pada versi kompiler sebelumnya dan mungkin bukan implementasi yang akan kami lakukan pada akhirnya. Kami akan membuat dokumen desain publik baru setelah kami memiliki ide yang lebih baik tentang implementasi baru

@ocombe Saya harus memberi +1 pada fitur ini. kebutuhan serius untuk itu sekarang lol :+1: Terima kasih telah membuat alat yang luar biasa! :)

Seperti yang saya pahami dalam dokumen desain saat ini, penulis perpustakaan AOT perlu menyediakan terjemahan untuk semua bahasa yang diperlukan oleh berbagai aplikasi yang menggunakan perpustakaan ini.
Sudahkah saya memahami ini dengan benar?

Ini adalah poin yang bagus @gms1.
Saya menguji ini di sini .
Sebagai penulis perpustakaan, Anda hanya perlu menambahkan tag i18n.
Anda tidak boleh mengkompilasi perpustakaan Anda ke " ngfactories " (lihat pembicaraan Jason Aden di ng-conf 2017), sehingga tag terjemahan tidak akan diganti. Dengan cara ini ketika Anda menjalankan perintah ng xi18n Anda juga akan mendapatkan terjemahan di xliff untuk file di folder node_modules Anda.

Jadi tidak, Anda tidak perlu memberikan terjemahan, tetapi menambahkan tag i18n dengan makna yang bermanfaat.

dikutip dari desain doc:

Untuk AOT kode sumber diubah untuk menggantikan panggilan layanan dengan terjemahan statis. Untuk melakukan itu kita akan menggunakan transformator TypeScript.

Jadi apa artinya ini jika perpustakaan sudut (AOT) akan diterbitkan biasanya dalam bentuk transpilasi? Saya belum menemukan referensi ke .metadata.json dalam dokumen ini

Anda tidak harus mengkompilasi perpustakaan Anda ke kode akhir, tetapi mempersiapkannya untuk dikompilasi oleh pengembang menggunakan kode Anda. Lihat apa yang @jasonaden sebutkan di sini . Ini juga berarti bahwa Anda dapat membuat perpustakaan Anda dapat diterjemahkan dengan menambahkan tag i18n.

@gms1 seperti yang saya katakan:

Kami memiliki dokumen desain tetapi didasarkan pada versi kompiler sebelumnya dan mungkin bukan implementasi yang akan kami lakukan pada akhirnya.

Dan kompiler AOT sedang diubah secara ekstensif untuk v5, seharusnya lebih mudah bagi lib untuk memublikasikan kode "aot-ready".
Untuk i18n kami ingin membuat ini semudah/fleksibel mungkin juga, mungkin akan seperti: perpustakaan dapat menerbitkan file terjemahan yang dapat Anda gunakan, tetapi Anda juga dapat menimpa jika Anda mau, dan Anda harus dapat menyediakan bahasa tambahan juga jika perpustakaan tidak mendukungnya secara default

Terima kasih @ocombe atas klarifikasi ini!

@ocombe Apakah ini berarti bahwa fitur ngx-translate akan tersedia di sudut itu sendiri?

@ montreal91 tidak ada bagian dari ngx-translate yang dapat diimplementasikan apa adanya ke dalam sudut, lib saya memiliki pendekatan yang sangat naif, ini berfungsi "kebanyakan" tetapi kami ingin jauh lebih efisien dengan kerangka kerja.
Karena itu, angular akan menyediakan fitur serupa (bahkan jika implementasi akhir akan berbeda).

Ini adalah pendekatan saya (FLUX) ketika saya sedang mengerjakan sistem notifikasi UI berdasarkan (https://github.com/PointInside/ng2-toastr). Masalahnya adalah bahwa konten notifikasi didefinisikan dalam panggilan layanan alih-alih templat untuk dikelola oleh sistem angular i18n (xi18n)

Bukan itu yang saya inginkan, tetapi ini adalah solusi _working_. Anda dapat _mengekstrak_ ide dari fragmen kode berikut. Semoga membantu :)

dimana saja

// 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>

Sekarang Angular 5 telah dirilis, apakah kita memiliki perubahan kapan perubahan pada modul i18n akan diintegrasikan?

Sepertinya fitur ini bergantung pada perubahan pada kompiler sudut, tetapi tim yang bertanggung jawab atas kompiler tampaknya kurang tertarik. Sepertinya tidak ada tugas atau PR atau melakukan:- (. Maaf untuk melampiaskan, tetapi permintaan fitur ini yang menjelaskan fungsionalitas sangat dasar yang ada di setiap kerangka terjemahan lainnya sekarang berusia lebih dari satu tahun. Saya telah memberikan berharap fitur penting ini akan tiba. Setidaknya untuk 5.x...

Teman-teman tetap tenang. Bukan hal yang konyol untuk diimplementasikan ke dalam kompiler AOT. Memiliki sedikit kepercayaan, @ocombe berkata:

"kemungkinan besar akan 5.x, @vicb sedang mengerjakan perubahan terakhir pada kompiler yang akhirnya akan memungkinkan ini"

Ya, kami sedang mengerjakan runtime i18n sekarang yang merupakan langkah pertama.
Runtime i18n berarti: satu bundel untuk semua bahasa, perpustakaan yang dikompilasi AOT dapat menggunakan i18n, dan mungkin nanti kemampuan untuk mengubah bahasa saat runtime. Ini juga berarti bahwa kita dapat melakukan terjemahan saat runtime, yang diperlukan untuk terjemahan di dalam kode (karena kita memerlukan parser runtime untuk terjemahan, dll...).
Setelah ini selesai, prioritas berikutnya adalah terjemahan di dalam kode.

Tetapi kami tidak dapat melakukan runtime i18n sebelum kami mengubah kompiler untuk menggunakan transformer TypeScript (yang telah dilakukan untuk 5.0)

Adakah yang tahu versi 5.x mana yang akan memiliki peningkatan i18n? Adakah yang dirilis dengan 5.0.0 itu sendiri?

5.0:

  • pipa i18n baru (tanggal/angka/persen/mata uang) yang tidak menggunakan API intl yang memperbaiki sekitar 20 bug karena sekarang mereka bekerja sama di semua browser + beberapa peningkatan lainnya (parameter lokal, format tambahan baru, parameter zona waktu untuk pipa tanggal, ...)
  • fungsi api i18n baru untuk perpustakaan dan komponen: https://next.angular.io/api?query=getlocale
  • integrasi yang lebih baik dengan klien

5.1 atau 5.2 (jika tidak ada pemblokir tak terduga):

  • waktu proses i18n

5.x:

  • terjemahan kode i18n (bukan hanya templat)

Dan hal-hal lain yang akan kami tambahkan di sepanjang jalan tetapi belum diputuskan (Anda dapat mengikuti https://github.com/angular/angular/issues/16477).

Hanya ingin tahu, meskipun saya sedikit terlambat, hanya dengan mempertimbangkan dukungan i18n dalam file TS, mengapa kita tidak memikirkan sintaks anotasi? (Saya menemukan seseorang telah menyebutkannya di atas juga)

Contohnya adalah:
@i18n (id='pesan1')
message1 = "Ini adalah pesan yang perlu diterjemahkan";

@i18n (id='dynamicMessage')
dynamicMessage = "Ini adalah pesan dinamis dengan {0}";

Dengan anotasi untuk dynamicMessage, kita dapat menginjeksi suatu fungsi melalui anotasi ke instance string ini, yang namanya format , kemudian kita dapat menggunakan seperti di bawah ini:
var finalMessage = dynamicMessage.format('value1')

Pendekatan serupa dapat dilakukan untuk menangani parameter bernama , dll.

Saya kira pertanyaannya bukan tentang bagaimana membuat pengalaman pengembang yang baik. Pertanyaannya adalah tentang kompilasi.

Juga apa yang terjadi jika Anda mengubah message1 ke string lain? Semua variabel i18n harus selalu konstan. Saya tidak berpikir menggunakan variabel akan berhasil sama sekali. Misalnya Symfony memiliki layanan penerjemah dengan fungsi terjemahan yang akan bekerja seperti ini dalam sintaks JS: let translated = this.translator.trans('Hello %name%', [{'%name%': nameVariable}]); yang akan menghasilkan: <source>Hello %name%</source> <target>Bonjour %name%</target>

@MickL inti dari terjemahan -aot saat ini adalah, buat program yang minimal dan efisien. Itu sebabnya pendekatan untuk terjemahan dinamis belum ada.
Saya sangat percaya bahwa pendekatan saat ini benar-benar bagus, dalam arti bahwa kami tidak menggunakan layanan dinamik untuk menerjemahkan string. Itu berarti jika Anda tahu bahwa beberapa teks statis, silakan terjemahkan dengan cara itu tanpa menggunakan layanan.

Masalah dengan terjemahan dinamis sederhana, yaitu jika Anda akan menerjemahkan string setiap kali Anda menampilkannya. Bukan cara yang benar-benar baik,
Mengapa?

  1. Karena Anda memiliki kamus beberapa bahasa di memori saat Anda tidak menggunakannya.
  2. Setiap kali Anda menampilkan teks dinamis, Anda harus membuka peta dan menemukan kunci, lalu menemukan terjemahan bahasa. SETIAP SAAT karena Anda memiliki "bahasa utama".

Dari sudut pandang saya, solusi masa depan harus:

  1. Backend memberi Anda teks yang ingin Anda terjemahkan.
  2. Ganti/(atau unduh dari backend yang merupakan pendekatan saat ini) setiap teks yang Anda tampilkan dalam bahasa saat ini/utama. (ganti semuanya dapatkan waktu, tetapi Anda tidak perlu menemukan dua kunci setiap kali Anda ingin menampilkan label sederhana).
  3. Hanya teks yang benar-benar dinamis yang dapat diganti dan/atau diminta ke backend.

Pikirkan tentang itu, jika Anda benar-benar memiliki teks dinamis untuk menunjukkan bahwa Anda dapat menerimanya dari backend, dan jika Anda benar-benar membutuhkan salinan "teks dinamis" itu, Anda selalu dapat menggunakan cache untuk itu.

Menurut saya, masalah ini tidak perlu dibahas lagi. Sebenarnya ada seorang pria (Olivier Combe) bekerja FULLTIME di i18n. AOT sangat istimewa dan banyak pekerjaan yang harus dilakukan sebelum membuat masalah ini mendekati mungkin. Segera kami akan memiliki terjemahan dinamis: Tidak perlu lagi membangun setiap bahasa secara terpisah! Ketika ini selesai, kami akan memiliki terjemahan dalam kode (masalah ini) nanti. Dia mengatakan jalan sampai masalah ini diselesaikan mudah-mudahan memakan waktu setengah tahun dari sekarang.

Jika Anda tertarik membaca pidatonya di Angular Connect pada 07.11.17 tentang masa kini dan masa depan i18n di Angular: https://youtu.be/DWet6RvhHWI?t=21m12s

Ini baunya seperti kasus penggunaan yang bagus untuk string templat yang diberi tag TypeScript ...

Ini bau secara umum. Saya mengunjungi utas ini sebulan sekali untuk memeriksa kemajuan dan berhenti kecewa karena harapan yang lebih rendah. Satu-satunya hal yang diinginkan pengembang adalah memiliki opsi yang sama untuk terjemahan string dalam kode seperti dalam template. Kode saya penuh dengan string templat terjemahan tersembunyi karena kurangnya fungsionalitas ini. Apakah ini akhirnya diselesaikan dengan layanan atau anotasi tidak relevan dan tidak masalah jika itu membutuhkan tambahan milidetik. Saya sudah melihat sesuatu untuk perubahan ketika saya memilih string dari kode. Satu-satunya persyaratan adalah kode tersebut diuraikan dan string yang relevan berakhir di file yang sama dengan format yang sama dengan terjemahan berbasis template saya.

@eliasre Anda dapat mencoba https://github.com/ngx-translate/i18n-polyfill jika Anda sedang terburu-buru untuk menerjemahkan kode
tidak ada janji bahwa itu akan sama, sebenarnya mungkin akan berbeda (seperti lebih mudah digunakan), ada batasan untuk apa yang mungkin sekarang... dan itu akan menambahkan ~80ko ke aplikasi Anda untuk digunakan lib itu

Anda dapat menggunakan ngx-translate jika Anda tidak ingin menunggu

@ocombe maukah Anda memberikan pembaruan tentang kemajuan sehingga kami dapat melacak dan merencanakan sesuai dengan jadwal pengembangan saat menunggu keputusan tentang plugin atau kerangka kerja apa yang akan digunakan? itu akan sangat membantu dan dihargai

@eliasre Saya pikir google ingin membuat solusi yang baik sekaligus. Tanpa merusak perubahan di masa depan. Saya setuju itu memakan waktu lebih lama dari yang kita kira.

Jangan repot-repot @ocombe yang malang dia bekerja sangat SANGAT keras!
Teruskan! :)

Bukan saya yang mengerjakan fitur ini, dan ini adalah liburan liburan, saya akan memberi tahu Anda segera setelah saya tahu lebih banyak

terima kasih @ocombe

terima kasih @ocombe , pembaruan apa pun akan sangat dihargai di sini. Saya telah mati-matian menunggu runtime i18n selama beberapa bulan terakhir, dan ETA build terakhir adalah 5.2. Bisakah Anda memberi tahu kami segera setelah Anda memiliki ETA yang diperbarui di sini?

Maaf karena terlalu gigih, tetapi membangun untuk 20 bahasa akhirnya menjadi sangat lambat saat ini.

Karena Angular 5.2 keluar dan sayangnya saya tidak dapat menemukan apa pun yang terkait dengan i18n (atau apakah saya mengabaikan sesuatu?) ... - @ocombe mungkin Anda dapat memperbarui kami tentang rencana rilis? Terima kasih banyak & terima kasih banyak atas usaha Anda di i18n!

@ocombe bukan orang yang kami tunggu di sini... lihat tautan youtube di komentar ini: https://github.com/angular/angular/issues/11405#issuecomment -343933617

Perencanaan terus berkembang. Setiap kali saya memberikan kemungkinan tanggal rilis, ternyata ada hal lain yang mendapat prioritas atau menjadi wajib dan tanggal itu bergeser sekali lagi. Saya tahu betapa mengecewakannya Anda semua yang menunggu fitur ini, dan saya melakukan semua yang saya bisa untuk meningkatkan prioritas.
Kami memiliki pertemuan besok untuk membahas backlog/perencanaan i18n, saya akan memberi tahu Anda jika saya mendapatkan sesuatu yang baru.

@ocombe jika Anda mendapatkan i18n dirilis bulan ini, saya akan membelikan Anda 24 bungkus bir kerajinan

Saya akan menambahkan 24 botol bir Jerman dan 24 botol lagi jika Anda bertanya apa yang dilakukan Elemen Angular dan dukungan perpustakaan. Sial tidak mendapatkan informasi apa yang terjadi mengerikan.

@ocombe Anda memiliki kesempatan langka sekali seumur hidup untuk mendapatkan 72 botol bir kerajinan mahal, dan membuat komunitas pengembang senang. Kami akan memenuhi janji kami jika Anda mencapai hal-hal ini teman saya.

@MickL Angualr Elments, seperti yang saya mengerti, ini akan memungkinkan kita membangun halaman non-SPA dan menggunakan komponen sudut sebagai elemen asli (sebagai widget sendiri juga)

Ya saya tahu. Ini adalah 2 fitur lain yang ditunggu semua orang tetapi tidak ada yang tahu apa statusnya dan kapan harus mengharapkannya...

Jika saja seseorang berjanji untuk menambahkan 27 botol bir terakhir, kita bisa mulai menghitungnya!
http://www.99-bottles-of-beer.net/language-javascript-1948.html

Saya akan menambahkannya, @ocombe : sebutkan merek fav Anda :D

Sunting: seseorang membuat layanan yang mirip dengan eth bounty bernama beerbounty :p

Seperti yang dijanjikan, sedikit pembaruan: kami masih bertujuan untuk merilis runtime i18n di v6, yang memberi kami waktu 5 minggu. Ini akan menjadi pendek, mungkin akan ditambahkan di salah satu rilis terakhir, dan itu akan berada di belakang bendera.
Runtime i18n harus datang dengan terjemahan kode, karena begitulah cara kerjanya untuk template juga (seharusnya menggunakan mekanisme yang sama).
Meskipun demikian, belum tentu layanan tersebut akan 100% siap, dan kami mungkin menundanya untuk memastikan bahwa kami tidak akan merusaknya segera setelah merilisnya, jika kami merasa itu adalah pilihan yang tepat. Tapi itu akan mengikuti runtime i18n dalam hal apa pun (itulah peta jalan kami), dan kami tidak memerlukan versi utama untuk merilisnya karena itu akan berada di belakang bendera, dan itu tidak boleh merusak apa pun).

Apa yang dapat mencegah kami untuk melepaskannya tepat waktu:

  • jika kami menemukan masalah yang tidak terduga (Anda tahu cara kerja pengembangan)
  • jika itu merusak aplikasi google internal karena kami mengacaukan di suatu tempat
  • jika sesuatu prioritas utama datang dan kita harus mengalihkan fokus kita
  • jika salah satu hal baru yang bergantung padanya diblokir atau ditunda (runtime i18n tergantung pada beberapa perubahan internal besar yang sedang dikerjakan oleh anggota tim lainnya)
  • Pengembang angularJS senior, telah menggunakan lib terjemahan PascalPrecht selama 3 tahun.
  • menggairahkan saya. Pemula sudut 2. Menjelajah dengan naif https://angular.io/guide/i18n
  • Berhasil mengintegrasikan i18n ke dalam proyek profesional saya
  • Menghabiskan sepanjang hari mengotak-atik semua label hard-code front-end, porting ke file xlf 100+kb
  • Perlu menerjemahkan label mentah dalam layanan ng
  • Mencarinya di google, ada di sini
  • Cari tahu tidak ada solusi sebelum Angular 6 berusia.
  • saya rn
    mfw

@Macadoshis Anda dapat menggunakan lib polyfill saya untuk saat ini: https://github.com/ngx-translate/i18n-polyfill

@Macadoshi sekarang bayangkan apa yang telah kita lalui sejak alpha.46 ! ;)

Terima kasih telah menunjuk i18n-polyfill kepada saya @ocombe , tapi saya akan menggunakan ngx-translate karena mendukung pemuatan async dari kunci terjemahan.
Pabrik i18n-polyfill untuk penyedia TRANSLATIONS tampaknya hanya mendukung pemuatan mentah sinkronisasi dari lokal tetap yang diketahui sebelum bootstrap.

// 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 seberapa dekat polyfill yang Anda tulis dengan apa yang dirilis? Adakah yang harus kita sadari, atau persiapkan? Juga, maukah Anda mencantumkan daftar fitur dengan i18n yang dirilis di versi 6, dan bagaimana pengujian dengan i18n?

Saya tidak memiliki detail lebih lanjut tentang layanan terjemahan kode untuk saat ini, kami akan mengerjakannya minggu depan mungkin (saya bepergian ke mountain view). Yang saya tahu adalah bahwa di balik layar itu akan mirip dengan goog.getMsg dari perpustakaan penutupan (karena itulah yang digunakan google secara internal untuk saat ini): https://github.com/google/closure-library /blob/db9bc1a2e71d4b6ee8f57eebe37eb0c6494e9d7e/closure/goog/base.js#L2379 -L2387 yang mirip dengan polyfill saya juga.

Di v6 kami akan merilis runtime i18n: satu bundel untuk semua lokal, terjemahan diselesaikan saat runtime, dan mungkin terjemahan kode jika kami punya waktu (jika tidak, itu akan segera menyusul). Semua itu akan berada di belakang bendera karena harus menggunakan renderer baru (disebut ng-ivy) yang tidak akan diuji dalam pertempuran.

Terima kasih! @ocombe ... kedengarannya sangat bagus!
Apakah akan ada perubahan dalam sintaks untuk terjemahan template? Saya sedang berpikir untuk menambahkan terjemahan ke proyek kami sekarang - tetapi tidak ingin mengulanginya sepenuhnya dalam beberapa minggu.

Tidak, sintaks template akan sama

Terima kasih @ocombe atas berita baiknya, ini sangat menjanjikan. Kesiapan produksi seperti apa yang dapat kita harapkan dari perender ng-ivy yang akan dirilis dengan v6? Saya mengerti itu tidak akan diuji pertempuran, tetapi masih akan siap untuk penggunaan produksi dan bekerja pada semua browser utama versi hampir saat ini, bukan?

Anda dapat mengikuti perkembangannya di sini: https://github.com/angular/angular/issues/21706
Saya tidak berpikir bahwa semuanya akan siap untuk v6, karena ini di bawah bendera kami akan terus maju bahkan setelah rilis v6 (ini bukan perubahan yang melanggar atau apa pun)
Sejujurnya saya tidak yakin apa semua itu :D
Saya tahu bahwa aplikasi hello world dari cli sudah berfungsi.
Saya pikir beberapa dari hal itu diperlukan untuk mendapatkan manfaat dari pengoptimalan perender baru, tetapi mungkin dapat berfungsi tanpa memeriksa semuanya
Yang sedang berkata, itu juga berarti bahwa itu tidak akan siap produksi, jangan pertaruhkan produk Anda dulu. Itu tidak akan diuji pada aplikasi google internal, dan kami mungkin perlu melakukan beberapa perubahan untuk memperbaikinya. Menggunakan penyaji baru adalah kebijaksanaan Anda sendiri dan risiko Anda sendiri

Apakah ini ada di v6-beta4 ?

Tidak. Periksa peta jalan ini, fitur ini diblokir oleh runtime i18n.

update @ocombe ?

PR pertama untuk runtime i18n telah digabungkan menjadi master, bersama dengan aplikasi demo hello world yang akan kita gunakan untuk menguji fitur-fiturnya. Ini bekerja saat runtime, dan mendukung terjemahan kode secara teoritis, bahkan jika belum ada layanan untuk itu.
Untuk saat ini dukungannya sangat minim (string statis), kami sedang berupaya menambahkan fitur baru (saya akan membuat ekstraksi berfungsi minggu depan, dan kemudian string dinamis dengan placeholder dan variabel).
Setelah itu kami akan melakukan layanan untuk terjemahan kode.
Segera setelah fitur baru selesai, fitur tersebut akan digabungkan menjadi master, Anda tidak perlu menunggu jurusan baru.

@ocombe i heart i18n fitur seharusnya sudah ada di sini di v4.3 !! Begitu banyak rilis tapi tidak ada di i18n. Dapatkah manajer tim sudut mengalokasikan lebih banyak pekerjaan/pengembang di atasnya saya dapat memahami Anda sendiri atau dua pengembang tidak dapat melanjutkan dengan cepat, fitur i 18n ini adalah fitur yang harus dimiliki untuk berpura-pura menjadi aplikasi bisnis /aplikasi besar dengan pembuatan cepat tentu saja kedua fitur ini adalah yang paling penting untuk aplikasi besar, bukan begitu? Terima kasih

Saya pikir satu-satunya hal yang bisa kami katakan kepada @ocombe adalah berterima kasih padanya atas semua upaya yang dia lakukan untuk fitur ini. Saya yakin jika tidak ada lagi pengembang bukan karena dia tidak memintanya. Biarkan dia melakukannya, saya yakin kita tidak akan menyesal ketika itu dirilis.

Hanya untuk referensi...

Saya memiliki alat alternatif untuk mengimpor dan mengekspor string, awalnya dikembangkan untuk digunakan dengan Aurelia, yang menyertakan dukungan untuk string yang disimpan dalam file json - ini cukup berguna, karena Webpack memungkinkan Anda untuk mengimpor json secara langsung ts Anda, memberikan kode Anda akses mudah ke string tersebut.

Alat ini juga berfungsi dengan templat Angular, dan memiliki banyak fitur praktis lainnya - gunakan jika Anda suka, atau jangan ragu untuk meminjam ide darinya untuk meningkatkan alat Angular. Ada juga pemuat Webpack berdasarkan ini - lihat tautan di dokumen.

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

Kami memiliki masalah yang lebih sederhana dan saya tidak yakin apakah kami memerlukan fitur yang akan datang (atau polyfill oleh @ocombe).

Kami mendefinisikan struktur semua bentuk reaktif dengan konstanta, di mana kami mengatur properti setiap elemen bentuk. Sebagai contoh:

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

Saat ini kami menggunakan ngx-translate , jadi di template kami menerjemahkan string seperti ini:

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

Kami sekarang ingin bermigrasi ke Angular i18n. Namun, karena tidak semua string kita ada dalam template, sepertinya kita tidak bisa menggunakan Angular i18n di luar kotak.

Situasi kami terlihat lebih sederhana daripada situasi di mana terjemahan perlu diambil saat runtime. Semua teks kita telah ditentukan sebelumnya dalam konstanta, dan dapat diganti pada waktu kompilasi, seperti halnya x18n saat ini untuk string dalam template.

Misalnya, kita dapat memiliki string yang lebih kompleks seperti berikut ini

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

Pada waktu kompilasi string dapat diganti menjadi:

placeholder: 'Your password'

Apakah ini sesuatu yang mungkin dipertimbangkan untuk implementasi?

Anda pasti bisa melakukannya dengan runtime i18n, Anda bisa menggunakan layanan i18n baru dalam pipa misalnya untuk mengubah placeholder Anda menjadi terjemahannya

Saya perhatikan utas ini telah dibuka untuk beberapa waktu, ini menunjukkan minat utama untuk mengembangkan situs multibahasa di Angular dengan cara yang sederhana, menangani teks HTML dan kode komponen dengan cermat.
ocombe jangan lupa untuk mengirim peringatan kepada semua pelanggan ketika itu akan dilakukan - saya mengerti akan segera terjadi pada Mei 2018. Dan terima kasih atas kontribusi Anda yang baik!

@ocombe haruskah kita menggunakan Ivy untuk dapat menggunakan layanan runtime ini atau akan bekerja dengan mesin lama juga?

itu hanya dengan ivy, yang tidak dapat Anda gunakan untuk saat ini karena belum selesai

Terima kasih atas semua kerja keras Anda @ocombe !

Ada kabar tentang seberapa cepat kami dapat menggunakan fitur-fitur baru ini?

Ivy dapat diaktifkan di angular 6 dengan flag compiler sekarang, dalam status pra-rilis. Bisakah fitur 18n baru ini digunakan menggunakan pra-rilis Ivy saat ini?

Belum, tetapi saya membuat kemajuan yang baik (bekerja penuh waktu untuk ini sekarang). Saya akan memposting pembaruan di sini setelah tersedia di master untuk diuji

terima kasih banyak @ocombe ! Begitu banyak orang yang mendapat manfaat dari kerja keras Anda. Kami semua sangat menghargainya!

@ocombe Apakah terjemahan statis di ts masih direncanakan? Maksud saya kompilasi penggantian ekspresi waktu, kemungkinan dengan transformasi TypeScript.
Jika tidak, apakah kita akan dapat memasang custom ts transform ke dalam pipa ng build tanpa mengekstrak ?

Saya tidak yakin untuk mengikuti apa yang Anda maksud @TinyMan ? Maksud Anda dapat menggabungkan terjemahan pada waktu pembuatan (seperti sekarang ini), atau dapat menggunakan terjemahan dalam kode ts (selain terjemahan template yang sudah kita miliki)?

@ocombe Maksud saya dapat menggunakan terjemahan di ts, tetapi tidak melalui layanan atau terjemahan DI / runtime. Maksud saya kompilasi terjemahan waktu tetapi untuk TypeScript. Seperti C preprosesor. Saya pikir itu direncanakan sesuai komentar vicb :

  • kami juga dapat mendukung terjemahan statis seperti yang kami lakukan hari ini untuk templat - string akan diganti pada waktu kompilasi, kinerja yang lebih baik tetapi satu versi aplikasi per lokal,

Misalnya, saya ingin bisa menulis:

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 !"),
}

Dan kemudian ini diubah menjadi sesuatu seperti (dalam fr):

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

Saat ini untuk tujuan itu saya menggunakan ngx-translate dengan penanda khusus untuk ekstraksi ( i18n dalam contoh ini), dan ketika saya perlu menampilkan pesan saya harus memanggil this.translate.instant(Notifications.newStory, ["TinyMan"]) yang menerjemahkan + interpolasi. Maksud saya adalah kita harus dapat menulis Notifications.newComment tanpa memanggil layanan terjemahan. Dan untuk interpolasi string kita dapat memiliki metode interpolasi yang hanya melakukan ICU dan interpolasi (string template sudah akan diterjemahkan)

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

Di sini kita hanya menyingkirkan permintaan HTTP terjemahan dan overhead layanan.

Saya harap itu menjelaskan?

Apa yang Anda gambarkan memang ada di peta jalan untuk i18n.
Untuk saat ini, https://github.com/ngx-translate/i18n-polyfill akan melakukan pekerjaan itu.

@TinyMan Saya belum yakin apakah itu akan melalui layanan atau fungsi global. Keduanya mungkin, tetapi layanan juga memiliki banyak keuntungan: Anda dapat mengejeknya untuk pengujian, atau menggantinya dengan milik Anda sendiri, Anda juga dapat mengubah perilakunya untuk setiap modul/komponen
Saya tahu bahwa secara internal Google akan menggunakan Closure i18n (via goog.getMsg ) yang merupakan fungsi global, dan fungsi tersebut kemungkinan besar akan digantikan oleh layanan selama kompilasi berdasarkan bendera global. Saya akan mencoba melihat apakah bendera itu juga dapat digunakan secara eksternal, tetapi saya tidak mengerti mengapa tidak. Tetapi jika Anda menggunakannya, itu untuk templat dan terjemahan kode

@ocombe Saya ingin mengucapkan terima kasih di sini juga. Saya sangat menghargai pekerjaan yang Anda lakukan dalam hal ini yang akan sangat membantu saya dalam pekerjaan saya. Satu pertanyaan: apakah ada cara, atau _akan_ ada cara, untuk melakukan kompilasi AOT yang hanya membuat satu set file bundel yang, ketika mencari teks, mereferensikan xlf saat runtime untuk mendapatkan string yang benar?

jadi intinya Anda akan membutuhkan 1 file xlf per bahasa ditambah 5 atau 6 file bundel. Saat ini, jika kita memiliki 10 bahasa dan kompilasi AOT lebih dari 50 file: satu set file bundel per bahasa...

Saya tidak tahu upaya atau kerumitan sesuatu seperti itu, tetapi akan menyenangkan untuk memiliki kompilasi tetapi hanya dengan 1 set file.

ya, itulah yang akan kami lakukan dengan ivy, runtime i18n
bundel aplikasi Anda sekali, dan muat terjemahan saat runtime (Anda dapat dengan malas memuat terjemahan)

@ocombe itu. adalah. menakjubkan.

Itu membuatku sangat bahagia luar biasa. TERIMA KASIH!

Tanpa kemampuan untuk menerjemahkan template luar, fitur i18n sama sekali tidak berguna bagi saya.

@ocombe Halo Olivier!
Ada pembaruan?

Terima kasih!

Jika selesai tidak masalah karena kita harus menunggu Ivy selesai, yang dijadwalkan untuk Angular 7 (sept/oct 2018)

Dengan Angular 7 masalah ini akan berumur dua tahun LOL.
Bagaimanapun, Ivy adalah hal yang paling menunda fitur baru ini...

@ocombe , senang mendengarnya. Kami saat ini terjebak menggunakan layanan i18n lawas yang kami luncurkan dari bawah ke atas murni karena alasan ini. Tidak dapat melakukannya di JS membuatnya sangat sulit untuk melakukan beberapa hal sederhana bagi kami:

  • Komponen dinamis
  • Mengintegrasikan dengan layanan pihak ke-3 di mana kami harus menyediakan beberapa teks lokal untuk
  • Menampilkan modal konfirmasi dinamis
  • Api kami mengembalikan kesalahan types . Dalam konteks kami, kami perlu melokalisasi kesalahan ini secara dinamis dan pendekatan yang didorong oleh template akan menjadi kludgy.
  • Kami ingin menggunakan TitleService seperti yang disarankan oleh tim Angular, tetapi tidak ada cara untuk menyediakan teks yang dilokalkan!

Saya agak ingin tahu bagaimana tim Angular menangani ini saat ini ...

Hai @vincentjames501 ,
Di perusahaan kami, kami mencoba melakukan hal yang sama seperti yang Anda lakukan sekarang, tetapi itu sangat merepotkan, jadi kami akhirnya menggunakan i18n-polyfill yang disebutkan sebelumnya di utas ini, dan sejauh ini berfungsi dengan baik.
Satu-satunya kelemahan yang kami miliki adalah ukuran bundel aplikasi kami. Kami memiliki tiga file terjemahan, dan setiap bundel berisi semuanya di dalamnya (kami belum menemukan cara untuk menghasilkan bundel hanya dengan terjemahan yang digunakannya). Namun semua ini hanyalah gangguan yang kami harap akan teratasi saat Ivy keluar.
Bersulang,

Saya telah menyertakan peta terjemahan dan mengekspornya kembali ke file environment.ts setiap bahasa. Ini berfungsi tanpa masalah, tidak termasuk dalam semua bundel, dan tidak memerlukan perpustakaan eksternal. Satu-satunya masalah yang saya miliki adalah karena setiap situs berbeda, saya tidak dapat memiliki pekerja layanan yang sama untuk semua bahasa dan jika seseorang beralih bahasa, situs saya tidak dapat mengetahui apakah dia sudah terdaftar untuk pemberitahuan push atau tidak ...

@ocombe ada berita di sudut 6?

Itu tidak akan ada di Angular v6, seperti yang dijelaskan di atas. Kami bergantung pada Ivy yang direncanakan untuk v7.

@ocombe bolehkah saya menyarankan agar Anda mengunci utas ini, sehingga hanya tim yang dapat memberikan pembaruan yang berarti saat diperlukan dan kami menghindari pertanyaan berulang yang terus Anda jawab?

Peretasan saya untuk digunakan dengan Angular saat ini menggunakan ng-template dan membuat tampilan tersemat secara terprogram:

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

dan kemudian di dalam file ts komponen:

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

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

Metode createTranslatedMessage mengembalikan pesan yang diterjemahkan. Meskipun saya menggunakan templat untuk menyatakan pesan yang tidak optimal, ini memungkinkan alat terjemahan CLI untuk mendaftarkannya dalam file xlf, dan saya memiliki cara untuk mendapatkan pesan yang diterjemahkan secara terprogram untuk digunakan di luar templat.

Semoga api akan bekerja untuk rute juga! Sebagai contoh

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

Jika fitur ini dirilis, apakah akan ada perubahan signifikan dari api i18n saat ini? Apakah Anda merekomendasikan saya memulai proyek saya dengan i18n sekarang atau haruskah saya menunggu i18n Api baru ketika Angular 7 dirilis?

Setiap pembaruan Kapan kami akan mendapatkan dukungan terjemahan run-time dan dinamis?

Terjemahan runtime selesai dan digabungkan (dengan ivy), tetapi sisi kompiler belum selesai.
Saya sedang mengerjakan ekspresi ICU sekarang.
Saya belum mulai mengkodekan terjemahan dinamis (layanan) tetapi itu mungkin hal berikutnya yang akan saya lakukan setelah ekspresi ICU.

@vincentjames501 Bisakah kita menggunakan i18n-polyfills dengan ekspresi ICU? Saya tidak punya solusi bagaimana menerapkannya

@ocombe , dapatkah Anda menjelaskan perbedaan antara terjemahan runtime vs dinamis?

mungkin tidak ada denominasi resmi, tetapi cara saya melihatnya adalah:

  • runtime: terjemahan diselesaikan saat runtime, artinya tidak selama build (seperti yang kami lakukan saat ini). Ini berlaku untuk semua jenis terjemahan (templat, atau dalam kode)
  • dinamis berarti Anda hanya tahu apa yang ingin Anda terjemahkan saat runtime, dan Anda tidak bisa melakukannya saat build. Ini sebagian besar berlaku untuk terjemahan "dalam kode", menggunakan layanan. Saya kira Anda dapat mempertimbangkan ekspresi ICU dinamis dalam arti bahwa mereka bergantung pada variabel, tetapi Anda masih dapat menghitung semua kemungkinan terjemahan pada waktu pembuatan karena jumlah kasus terbatas.

Saya menunda menambahkan dukungan i18n ke proyek saat ini yang sedang kami kembangkan tetapi kami semakin dekat dengan rilis, adakah ide apakah ini akan menjadi final di sudut 7? Atau haruskah saya mempertimbangkan cara lain untuk menambahkan terjemahan?

@andrei-tatar i18n bekerja dengan sempurna sejak Angular 2. Satu-satunya kelemahan:

  • Tidak ada terjemahan kode (masalah ini) -> Jika Anda membutuhkannya, gunakan i18n-polyfill
  • Jika Anda membuat AOT (disarankan), aplikasi harus dibuat untuk setiap bahasa secara terpisah
  • Karena setiap aplikasi dibuat secara terpisah, saat mengganti bahasa, Anda harus memuat ulang halaman

Untuk dua poin terakhir Anda bisa menggunakan @ngx-translate sebagai gantinya. Tetapi ini bekerja secara berbeda dari i18n bawaan Angular sehingga pembaruan selanjutnya dapat memakan waktu. Untuk polyfill, pembaruan tidak akan memakan waktu lama dengan kemungkinan tidak ada perubahan yang mengganggu.

@ocombe

Bagaimana kami dapat menangani operator bersyarat menggunakan fitur Angular i18n

[email protected]> menulis:

@shobhit12345 https://github.com/shobhit12345

Kami menggunakan ngSwitch untuk membuat template semua pesan, sehingga kami dapat melampirkan tag i18n ke
mereka secara individu.

BersembunyiMenunjukkanSejarah

Kami sering menggunakan metode ini untuk mengatasi terjemahan dinamis yang hilang.
Dengan sedikit pemikiran, sejumlah teks yang mengejutkan dapat diungkapkan dalam
cara ini di template. Pola umum adalah memiliki array pesan,
dan kemudian gunakan ini dengan ngFor dan ngSwitch untuk membuat template pesan,
sesuatu seperti ini:

ts

pesan = [ 'ini pesan pertama', 'ini pesan kedua' ]

html


i18n="@@firstMesssage">Ini adalah pesan pertama
i18n="@@secondMesssage">Ini adalah pesan kedua

Ini agak bertele-tele - tetapi berhasil!


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/angular/angular/issues/11405#issuecomment-415731284 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AGwM6jcWIpwtGxhkH1fwnVXNagRxmMnoks5uT-LxgaJpZM4J2pkr
.

Jika selesai tidak masalah karena kita harus menunggu Ivy selesai, yang dijadwalkan untuk Angular 7 (sept/oct 2018)

Sudah Oktober. Apakah menurut Anda kami akan memiliki fitur baru pada akhir Oktober?

@lizzymendivil menurut https://is-angular-ivy-ready.firebaseapp.com Ivy 65% ​​selesai dan sepertinya tidak mungkin selesai hanya dalam 30 hari

Ya, ivy tidak akan selesai dalam satu bulan.

@ocombe bisakah Anda mengunci ini sehingga hanya Anda yang dapat memposting pembaruan. agak menjengkelkan untuk mendapatkan semua notifikasi "kapan selesai?" komentar

@ocombe sepertinya Ivy sekarang sekitar 94%, apakah menurut Anda ini mungkin siap pada akhir tahun?

Saya tidak berpikir begitu. Menjadi fitur siap dan bebas bug (= dapat digunakan) sangat berbeda. Kami sebagian besar bekerja untuk memperbaiki keadaan sekarang.

@ocombe dapatkah kita percaya bahwa i18n datang sebelum sudut 8?

Saya tidak berpikir begitu. Menjadi fitur siap dan bebas bug (= dapat digunakan) sangat berbeda. Kami sebagian besar bekerja untuk memperbaiki keadaan sekarang.

Ok, terima kasih atas balasannya yang cepat, sangat dihargai.

Setiap pembaruan @ocombe yang seharusnya kita harapkan (Akhir Tahun saya lihat di beberapa komentar terakhir) bagian "Terjemahan Kode" tersedia bersama dengan "Terjemahan Template" untuk dukungan I18N dengan Angular? Kami berpikir untuk klub ngx-translate-polyfill untuk hal yang sama bersama dengan fitur Angular I18n tetapi ada juga tampaknya dukungan xlf tidak tersedia untuk menggabungkan file xlf yang ada dengan menggunakan https://github.com/biesbjerg/ngx-translate-extract CLI .

Terima kasih !

@Abekonge

Kami menggunakan ngSwitch untuk membuat template semua pesan, sehingga kami dapat melampirkan tag i18n ke masing-masing pesan.
Ini agak bertele-tele - tetapi berhasil!

Terima kasih untuk sarannya! Tampaknya yang paling mudah untuk dipahami. Pertanyaan saya adalah, apakah Anda masih menggunakan implementasi ini dalam situasi di mana array memiliki "banyak" nilai, seperti 10 atau lebih? Sepertinya kodenya akan menjadi sangat besar.

Saya tidak tahu apakah kita memilikinya dengan sebanyak itu, tetapi mengapa tidak. Jika pesan itu digunakan di beberapa tempat, kami membuat komponen i18n kecil yang pada dasarnya hanya sakelar dan tag i18n.

David

Den 23. jan. 2019 kl. 19.24 skrev Andrew Bissada [email protected] :

@Abekonge

Kami menggunakan ngSwitch untuk membuat template semua pesan, sehingga kami dapat melampirkan tag i18n ke masing-masing pesan.
Ini agak bertele-tele - tetapi berhasil!

Terima kasih untuk sarannya! Tampaknya yang paling mudah untuk dipahami. Pertanyaan saya adalah, apakah Anda masih menggunakan implementasi ini dalam situasi di mana array memiliki "banyak" nilai, seperti 10 atau lebih? Sepertinya kodenya akan menjadi sangat besar.


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub, atau matikan utasnya.

Cara menggunakan i18n-polifills di kelas Validator. Saya tidak dapat mengirim pesan validator rahasia pengguna melalui layanan i18n.

//Dalam komponen
this.crForm= this.fb.group({
nama belakang: [''],
ePassword: [''],
}, { validator: AccValidator baru(this.i18n).validate()}
);

//Validator

import { AbstractControl, ValidationErrors, FormGroup, FormControl } dari '@angular/forms';
impor { I18n } dari '@ngx-translate/i18n-polyfill';
kelas ekspor AccValidator{
konstruktor (i18n: I18n)
{

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

mendapatkan kesalahan di bawah ini

Galat GALAT: Tidak tertangkap (dalam janji): TypeError: i18n bukan fungsi
TypeError: i18n bukan fungsi
di FormGroup.eval [sebagai validator] (acc-validator.ts:9)
di FormGroup.AbstractControl._runValidator (forms.js:3433)
di FormGroup.AbstractControl.updateValueAndValidity (forms.js:3387)
di FormGroup baru (forms.js:4326)
di FormBuilder.group (forms.js:7864)

@ocombe

Cara menggunakan i18n-polyfills dengan const dalam file .ts

ekspor const glossayModel= () => [
{
judul: 'data uji',
aktif: benar,
data: [

        [
            {
                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, pilih, Medis {Kedokteran} Gigi {Gigi} Medis & Gigi {Kedokteran & Gigi} Bencana & Gigi {Bencana & Gigi} Katastropik {Bencana} }
{VAR_SELECT, pilih, Medis {Medical} Dental {Dental} Medical### & Dental {Medical y Dental}
Katastropik ### & Gigi{Bencana y Gigi} Katastropik {Bencana} }

Ketika saya menggunakan ekspresi ICU dengan karakter khusus , itu tidak mengubah .

@ocombe Bagaimana menangani remah roti menggunakan i18n-polyfills?

ekspor const rute: Rute = [
{
jalur: '',
komponen: Komponen Rumah,
data: {
judul: 'Rumah',
remah roti: 'Beranda'
}
}
]

@ocombe

Cara menggunakan i18n-polyfills dengan const dalam file .ts

ekspor const glossayModel= () => [
{
judul: 'data uji',
aktif: benar,
data: [

        [
            {
                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."
            }

]]}];

Anda dapat menggunakan seperti ini
{
data: 'data uji',
judul: this.i18n({ nilai: 'Nama', id: 'nama' }),
}
menyuntikkan polyfill I18n dalam konstruktor komponen seperti ini
i18n pribadi: I18n
Saat menggunakan terjemahan dalam file ts, Anda perlu menggunakan ngx-extractor dan xliffmerge agar file ts tersebut diterjemahkan. https://www.npmjs.com/package/ngx-i18nsupport

@ JanneHarju
itu tidak berfungsi, tidak mendapatkan data dalam file xlf.

Ini skrip terjemahan saya:
"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",

dan inilah xliffmerge.json

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

@ JanneHarju
Ya saya menggunakan konfigurasi yang sama , dan dapat mengekstrak pesan .ts dalam file xlf .

Tetapi const yang saya miliki di file .ts yang berbeda

ekspor const glossayModel= () => [
{
}

saya mengimpor komponen , ketika saya mencoba menggunakan i18n dengan const , itu tidak mengekstraksi nilai .

Bagaimana jika Anda menggunakan nilai const seperti penyedia.

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

kode mungkin rusak tetapi Anda mungkin mendapatkan poin.

bagaimana menerjemahkan remah roti

rute const: Rute = [
{
jalur: './enroll-new.component',
komponen: DaftarkanNewComponent,
data: {
remah roti: 'Pendaftaran'
},
}
]

dapatkah Anda berhenti menggunakan utas ini sebagai utas dukungan untuk i18n-polyfill atau masalah lainnya? jika Anda memiliki pertanyaan tentang i18n-polyfill, ajukan masalah di repo itu.
@ocombe mungkin Anda bisa mengunci topik ini? hampir semua yang penting harus ditutupi.
apa versi sudut yang Anda rencanakan untuk merilis dukungan i18n yang disebutkan dalam topik ini?

Ya, terkunci untuk saat ini.
Kami bekerja keras agar ivy tersedia dengan v8 sebagai beta keikutsertaan. Runtime i18n akan dapat digunakan dengan penutupan google (apa yang digunakan google secara internal) yang akan memungkinkan kami men-debugnya (ini adalah perubahan yang sangat besar). Untuk orang lain, Anda akan dapat menguji ivy dengan i18n tetapi Anda tidak akan dapat memuat terjemahan. Aplikasi akan berjalan dengan bahasa asli yang digunakan untuk membuat kode aplikasi.
Layanan runtime yang diperlukan untuk benar-benar menerjemahkan saat ini mengembalikan teks yang belum diterjemahkan. Karena kami semua sedang memperbaiki bug dengan kode yang ada, fitur baru akan dibatasi setelah rilis. Kami akan mengerjakannya setelah v8 keluar, itu harus menjadi tugas pertama saya.
Saya akan menambahkan pembaruan dan membuka utas ini setelah kami memiliki beberapa berita.

Untuk apa nilainya, tag $localize baru yang sedang kita kerjakan dapat digunakan secara terprogram.

Misalnya

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

Dan kemudian akan dapat memberikan terjemahan untuk Hello {$name}! yang dapat diganti pada waktu kompilasi (atau waktu berjalan).

Ini sekarang tersedia (jika tidak didokumentasikan).

Apakah halaman ini membantu?
0 / 5 - 0 peringkat