2013-12-02 7 views
11

Я использую Dart для создания приложения Polymer. Поскольку я использую возможности интернационализации Дарта в составе элементов Polymer, я хочу инициализировать сообщения о интернационализации до создания элемента Polymer и отображать соответствующие сообщения для данного языка в элементе Polymer.Как инициализировать интернационализацию для полимерного элемента перед его загрузкой Page

Как это можно сделать? Кто-нибудь успешно использовал Полимер с интернационализацией?

ps. Я последовал за this example, чтобы настроить интернационализацию

Ниже приведено по умолчанию приложение Polymer от Dart Editor плюс добавленный мной код.

messages_en.dart

library messages_en; 

import 'package:intl/intl.dart'; 
import 'package:intl/message_lookup_by_library.dart'; 

final messages = new MessageLookup(); 

class MessageLookup extends MessageLookupByLibrary { 

    get localeName => 'en'; 

    final messages = { 
    "myMsg" :() => Intl.message("MY MESSAGE") 
    }; 

} 

messages_all.dart

library messages_all; 

import'dart:async'; 
import 'package:intl/message_lookup_by_library.dart'; 
import 'package:intl/src/intl_helpers.dart'; 
import 'package:intl/intl.dart'; 
import 'messages_en.dart' as en; 

MessageLookupByLibrary _findExact(localeName) { 
    switch (localeName) { 
    case 'en': return en.messages; 
    default: return null; 
    } 
} 

initializeMessages(localeName) { 
    initializeInternalMessageLookup(() => new CompositeMessageLookup()); 
    messageLookup.addLocale(localeName, _findGeneratedMessagesFor); 
    return new Future.value(); 
} 

MessageLookupByLibrary _findGeneratedMessagesFor(locale) { 
    var actualLocale = Intl.verifiedLocale(locale, (x) => _findExact(x) != null); 
    if (actualLocale == null) return null; 
    return _findExact(actualLocale); 
} 

clickcounter.dart

import 'package:polymer/polymer.dart'; 
import 'package:intl/intl.dart'; 
import 'dart:async'; 
import 'messages_all.dart'; 
import 'messages_en.dart' as en; 

/** 
* A Polymer click counter element. 
*/ 
@CustomTag('click-counter') 
class ClickCounter extends PolymerElement { 
    @published int count = 0; 

    @observable var messagesLoaded = false; 

    ClickCounter.created() : super.created() { 
    var enMessagesFuture = initializeMessages('en'); 

    Future.wait([enMessagesFuture]).then((_) => messagesLoaded = true); 
    } 

    void increment() { 
    count++; 
    } 
} 

clickcounter.html

<polymer-element name="click-counter" attributes="count"> 
    <template> 
    <style> 
     div { 
     font-size: 24pt; 
     text-align: center; 
     margin-top: 140px; 
     } 
     button { 
     font-size: 24pt; 
     margin-bottom: 20px; 
     } 
    </style> 
    <div> 
     <button on-click="{{increment}}">Click me</button><br> 
     <span>(click count: {{count}})</span> 
     <br> 
     <br> 
     <span>current locale: {{Intl.getCurrentLocale()}}</span> 
     <br> 
     <br> 
     <template if="{{messagesLoaded}}"> 
     <span>intl message: {{How can I extract myMsg here?}}</span> 
     </template> 
    </div> 
    </template> 
    <script type="application/dart" src="clickcounter.dart"></script> 
</polymer-element> 

ответ

4

я написал образец для этого, которые вы можете найти на https://github.com/dart-lang/sample-polymer-intl/blob/master/README.md или увидеть https://www.dartlang.org/samples/ под "Полимер и интернационализация"

Эфирное бит выглядит следующим образом

// Polymer should call this method automatically if the value of 
// [selectedLocale] changes. 
void selectedLocaleChanged() { 
    // We didn't provide en_US translations. We expect it to use the default 
    // text in the messages for en_US. But then we have to not try and 
    // initialize messages for the en_US locale. dartbug.com/15444 
    if (selectedLocale == 'en_US') { 
    updateLocale('en_US'); 
    return; 
    } 
    // For the normal case we initialize the messages, wait for initialization 
    // to complete, then update all (all 1 of) our messages. 
    initializeMessages(selectedLocale).then(
     (succeeded) => updateLocale(selectedLocale)); 
} 

// When the user chooses a new locale, set the default locale for the 
// whole program to that and update our messages. In a large program this 
// could get to be a large method. Also, other components might want to 
// observe the default locale and update accordingly. 
void updateLocale(localeName) { 
    Intl.defaultLocale = selectedLocale; 
    helloWorld = helloFromDart(); 
} 
+0

Привет, Алан, я добавил свой код выше. У меня есть пара вопросов: 1) 'Intl.getCurrentLocale()' ничего не печатает; нужна ли интернационализация дополнительной инициализации? 2) Как напечатать интернационализированную строку 'myMsg' в' clickcounter.html'? – Peter

+0

Intl.getCurrentLocale() и Intl.defaultLocal return 'en_US' для меня, используя предоставленный вами код. В отладчике, а не в HTML, мне еще нужно это попробовать. –

+1

@Alan Knight Надеюсь, вы не возражаете, что я добавлю ссылку для примера интернационализации/локализации, представленную здесь в группе Dart: https://codereview.chromium.org/105073003 –

9

У меня есть что-то работающее:

добавить геттер к ClickCounter

String get locale => Intl.getCurrentLocale(); 

и изменить HTML для

текущей локали: {{локали}}

создать трансформатор

library i18n_transformer; 

import 'package:polymer_expressions/filter.dart' show Transformer; 
import 'package:intl/intl.dart' show Intl; 

class I18nTransformer extends Transformer<dynamic,String> { 
    Map<String,dynamic> _labels; 
    String language; 
    String missingIndicator; 
    I18nTransformer(this._labels, {this.language: 'en', this.missingIndicator: '#'}); 

    String forward(params) { 
    String id; 

    if(params is String) { 
     id = params; 
    } else if(params is Map) { 
     if(!(params['0'] is String)) { 
     throw 'Error: The first list element must contain the label id as string.'; 
     } 
     id = params['0']; 
    } else { 
     throw 'Error: The I18nTransformer expects either a label id as string or a list containing a label id and parameters.'; 
    } 

    var msg = Intl.message('', name: id); 
    if(msg == null || msg.isEmpty) { 
     return '${missingIndicator}(${language}-${params})'; 
    } 
    } 

    dynamic reverse(String label) { 
    return 'reverse not supported'; 
    } 
} 

и добавить следуя вашему ClickCounter

final I18nTransformer i18n = new I18nTransformer(null, language: 'en'); 

и в HTML

<p>{{ 'myMsg' | i18n }}</p> 
<p>{{ 'myMsg2' | i18n }}</p> <!-- sample output for a not existing message --> 

Комментарий:

Вы могли бы сделать более простой трансформатор < String, String >, но я выбираю использовать трансформатор < динамический, String >

быть способный предоставить дополнительные параметры (еще не реализованные в трансформаторе) в форме

{{ {0: 'myMsg', 1:'x'} | i18n }} 

Список литералы пока не поддерживаются в PolymerExpressions и поэтому вы должны добавить некоторые фиктивные ключи, как 0, 1, ...

В моей реализации первый ключ должен быть 0, чтобы работать, как вы может видеть в коде.

+0

Спасибо, @zoechi! – Peter

Смежные вопросы