【问题标题】:Play Framework 2.0 - issue in rendering viewPlay Framework 2.0 - 渲染视图中的问题
【发布时间】:2013-11-25 12:01:11
【问题描述】:

我按照这个链接https://github.com/julienrf/play-jsmessages/commit/3f67083e296edc039af6ed7fc0fe698a282d01b5在javascript中实现i18N。

Application.java
===================
package controllers;

import java.util.HashMap;
import java.util.Map;
import play.i18n.Messages;
import play.i18n.Lang;
import play.*;
import play.mvc.*;
import jsmessages.JsMessages;

import views.html.*;

import models.Session;

public class Application extends Controller {

    private static Session session;
    final static JsMessages messages = new JsMessages(play.Play.application());

    /**
     * Loads the application
     * @return
     */
    public static Result index() {
        return load();
    }
    public static Result jsMessages() {
        System.out.println("in jsMessages");
        return ok(messages.generate("window.Messages")).as("application/javascript");
    }

    /**
     * Initial load function, clears all stored session data
     * @return Redirect to homepage.html
     */
    public static Result load() {
        System.out.println("in load1");
        session = new Session();
        changeLang("fr");
        jsMessages();
        return ok(mainpage.render(messages));
    }


    public static Result reset() {
        session = new Session();
        return ok();
    }

    public static Session getSession() {
        if(session == null) {
            session = new Session();
        }
        return session;
    }
}

HTML which is rendered properly if i don't include i18n code for javascripts
mainpage.scala.html
==========================
@(messages: jsmessages.JsMessages)
<html>
<head>
@messages.html("window.Messages")
</head>

//some code goes here

</html>


javascript loaded on rendering homepage.scala.html
Main.js
======
// some code goes here
alert(Messages('first'));
//some code goes here


If I am not including i18n code in Application.java , mainpage.scala.html and main.js , my application is working fine but after including i18n code , page is not getting loaded.

根据我的理解,问题在于渲染,因为从 load() 和 jsMessages() 返回了两个结果。请建议我如何同时渲染 javascript 和 html 或任何其他方式,以便可以解决此问题。

【问题讨论】:

    标签: javascript html playframework-2.0


    【解决方案1】:

    您必须选择在文件(路由)中加载“jsMessages”还是在模板中显示它们。

    第一个场景,然后你使用:

    // Controller:
    public static Result jsMessages() {
        System.out.println("in jsMessages");
        return ok(messages.generate("window.Messages")).as("application/javascript");
    }
    
    // Route file:
    GET     /messages.js                controllers.Application.jsMessages()
    
    // Template:
    <script type="text/javascript" src="@routes.Application.jsMessages()"></script>
    

    第二种情况,然后删除public static Result jsMessages() 并:

    // Controller
    public static Result load() {
        System.out.println("in load1");
        session = new Session();
        changeLang("fr");
        return ok(mainpage.render(messages.generate("window.Messages")));
    }
    
    // Template:
    @(messages: String)
    <script type="text/javascript">@messages</script>
    

    【讨论】:

    • 我尝试实现第二种方法。在我的旧方法中,返回的消息是 JsMessages 类型,我正在使用 alert(Messages('first')); 获取 js 中任何键的值;在您的第二种方法中,返回的值是 String 类型,因此如何在 js 中获取任何特定键的值
    • 我对您的第一种方法有一个疑问,即路由文件中的 messages.js 是控制器中存在的 jsMessages() 的响应??
    【解决方案2】:

    注意:这不是您问题的直接答案,只是对其他方法的建议

    您根本不需要使用 Play 的控制器,而是可以使用放置在公共资源中的纯 JS 文件。假设您有 2 种语言,其中一种是默认语言(假设是英语),在这种情况下,您只需声明一个带有翻译标签和一些 getter 的对象,即:

    /public/i18n/messages.js

    var messages_default = {
       'save': 'Save',
       'delete': 'Delete',
       'warning': 'You can\'t do that'
    }
    
    function jsMessage(key) {
        var translated = messages[key];
        if (typeof translated === "undefined") {
            translated = messages_default[key];
            if (typeof translated === "undefined") {
                translated = key;
            }
        }
        return translated;
    }
    

    这样您就可以为每种语言创建一个新文件并只为其添加翻译(注意:没有_default 后缀)

    /public/i18n/messages_de.js使用谷歌翻译器进行'翻译,不要怪我;)):

    var messages = {
        'save': 'Sparen',
        'delete': 'Löschen',
        'warning': 'Sie können nicht tun'
    }
    

    在 Play 的本地化文件中(仅适用于非默认语言!conf/messages.de 在这种情况下)为附加语言 JS 文件的路径添加标签,即:

    add_i18n = i18n/messages_de.js
    

    所以最后你可以将它包含在德语版本中,或者使用简单条件跳过默认语言(请记住,对于不存在的标签,Play 的 Messages 返回密钥)

    <script src='@routes.Assets.at("i18n/messages_default.js")'></script>
    @if(Messages("add_i18n") != "add_i18n")){
        <script src='@routes.Assets.at(Messages("add_i18n"))'></script>
    }
    

    所以最后你可以在 JS 中使用它:

    <script>
        alert( jsMessage('warning') );
    </script>
    

    【讨论】:

    • 我按照以下步骤操作: 1) 创建 /public/i18n/messages.js 并复制您提到的代码。 2) 创建 /public/i18n/messages_de.js 并复制代码 3) 创建 /conf/messages.de 文件并添加键值对。 4) 在 application.conf 文件中写了 add_i18n = i18n/messages_de.js 5) 在 mainpage.scala.html 中写了你提到的 routes.asset 代码 6) 写了 alert(Messages('save'));在 main.js 中。但它不起作用。如果我在任何地方出错,请纠正我。
    • 检查我当前编辑的代码的最后一个sn-p(使用jsMessage(key)
    • 我包含了警报消息,但现在它在这一行失败了 var translate = messages[key];说消息没有定义
    • 在我提出问题的方法中,我们可以直接从 jsMessages() 获取 javascript 响应到我的 main.js,而不是通过 mainpage.scala.html 路由
    猜你喜欢
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    • 2020-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多