【问题标题】:How to support i18n with kotlin js如何使用 kotlin js 支持 i18n
【发布时间】:2020-11-11 20:55:06
【问题描述】:

我目前正在尝试将 i18n 支持添加到 kotlin js 项目(无反应)。

return document.create.div {
        span("mid-title") {
            +i18n here (ResourceBundle.getBundle()?)
        }....
  • 添加了资源包文件(strings.properties、strings_en.properties)
  • 试图通过 ResourceBundle.getBundle 获取它们
  • 找到了github ,但不喜欢这种方法

那么有没有一种方便的方法可以使用 kotlin js?

更新:

 fun loadJSON(callback: (response: String) -> Unit) {
    val xobj = XMLHttpRequest()
    xobj.overrideMimeType("application/json")
    xobj.open("GET", "test.json", true)
    xobj.onreadystatechange = {

        if (xobj.readyState.toInt() == 4 && xobj.status.toInt() == 200) {
            // Required use of an anonymous callback
            // as .open() will NOT return a value but simply returns undefined in asynchronous mode
            callback(xobj.responseText);
        }
    }
    xobj.send(null)
}

更新 2:

现在知道了

就像我在使用 javascript 加载文件之前所写的那样。之后,我有了 Json 对象,我可以在其中按键获取值。我还添加了一个重载来替换字符串中的参数。此外,我添加了一个 MuatableStateFlow 变量来观察语言的加载状态。但请记住,这个概念总是需要在服务器上运行。在本地,您会收到 CORS 错误

【问题讨论】:

  • 我相信 ResourceBundle 是 JVM 特定的,对于 Kotlin/JS,我认为,你可以尝试任何 JS i18n 库。
  • 另外,您可以找到一些 kotlin 多平台解决方案,例如github.com/fluidsonic/fluid-i18n
  • 对流体的使用确实很有趣,但不适合我的使用方式。我们正在使用 transifex,所以我需要一种从 json 或属性文件中获取我们自己的 defs 的方法。目前我正在尝试 javasrcipt 方法。更新
  • @coffeLord 你能给我一些示例回购吗?我正在尝试实现相同的设置并且无法设置。我也在使用 Maven。

标签: internationalization kotlin-js


【解决方案1】:
class LanguageSupport(private val folder: String = "", private val lang: String) {
    private lateinit var currentLang: Json

    private val languageMutableStateFlow = MutableStateFlow<LanguageSupportState>(
        LanguageSupportState.LanguageInit
    )
    val languageStateFlow: StateFlow<LanguageSupportState> = languageMutableStateFlow

    init {
        loadJSON()
    }

    fun get(key: String): String {
        val value = currentLang[key]
        check(value != null) {
            throw Exception("key not found to load language definition")
        }
        return if (value is String) {
            value
        } else {
            throw Exception("value of key is not a string")
        }
    }

    fun get(key: String, vararg placeholders: String): String {
        val value = currentLang[key]
        check(value != null) {
            throw Exception("key not found to load language definition")
        }
        return if (value is String) {
            var finalValue: String = value
            for (item in placeholders) {
                finalValue = finalValue.replaceFirst(PLACEHOLDER, item)
            }
            finalValue
        } else {
            throw Exception("value of key is not a string")
        }
    }

    private fun loadJSON() {
        val xobj = XMLHttpRequest()
        xobj.overrideMimeType("application/json")
        xobj.open("GET", "${folder}test_${lang}.json", true)
        xobj.onreadystatechange = {

            if (xobj.readyState.toInt() == 4 && xobj.status.toInt() == 200) {
                // Required use of an anonymous callback
                // as .open() will NOT return a value but simply returns undefined in asynchronous mode
                currentLang = JSON.parse(xobj.responseText)
                languageMutableStateFlow.value = LanguageSupportState.LanguageLoaded
            }
        }
        xobj.send(null)
    }

    companion object {
        const val PLACEHOLDER = "%s"
    }
}

sealed class LanguageSupportState {
    object LanguageLoaded : LanguageSupportState()
    object LanguageError : LanguageSupportState()
    object LanguageInit : LanguageSupportState()
}

因为我使用 Koin

single { (folder: String, language: String) ->
        LanguageSupport(
            folder = folder,
            lang = language,
        )
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-20
    • 2015-02-15
    • 1970-01-01
    • 2013-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多