PlayFramework HTML, переменная в Javascript?

Представьте себе простое игровое действие, определенное как

def reactTest = Action {
    request => Ok(views.html.hello("JOHN"))
}

и hello.scala.html выглядит так, используя простой пример React.js:

@(name: String)

....

<div id="example"></div>
<script type="text/jsx">
  React.render(
  <h1>Hello, @name!</h1>,     <---- NAME PARAMETER USED HERE
  document.getElementById('example')
);
</script>

Это работает отлично, и в результате будет "Привет, ДЖОН!" стр. Теперь я знаю, что код Scala выполняется на сервере, а код JS - на клиенте, но мне интересно, есть ли способ передать @name параметр к тому же коду javascript (jsx), если такой код был в отдельном файле.js, и <div> будет выглядеть так:

<div id="example"></div>
<script type="text/jsx" src="@routes.Assets.at("javascripts/hello.js"></script>

Будет ли способ передать @name параметр к сценарию в hello.js?

2 ответа

Решение

Вы можете сохранить все, что вы хотите, в глобальной переменной JS, а затем обращаться к ней в любое время.

Например, предположим, что вы хотите использовать пользовательский объект в вашем скрипте. Имея этот шаблон HTML

@(user: User)

<html>
<body>
    <script>
        var MyUserObject = {};
        MyUserObject["name"] = "@user.name";
        MyUserObject["age"] = @user.age;
    </script>
    <!-- ... -->
    <script src="your_component.js"></script>
</body>

тогда в вашем включенном js вы можете сделать что-то вроде этого:

(function(user) {
    alert("Hello " + user.name + ". You are " + user.age + " years old");    
})(MyUserObject);

Затем вы можете улучшить это, используя карту значений, которые вы хотите использовать, или, возможно, визуализировать ваш объект как JSON и проанализируйте его на стороне JS:

def reactTest = Action {
    request => Ok(views.html.hello(Json.toJson(user)))
}

// and then

@(user: String)

<html>
<body>
    <script>
        var MyUserObject = JSON.parse("@user");
    </script>
    <!-- ... -->
    <script src="your_component.js"></script>
</body>

Не идеально, но лучше, чем рендеринг в файлах JS IMO.

@routes... в:

<script type="text/jsx" src="@routes.Assets.at("javascripts/hello.js"></script>

можно изменить на:

@routes.YourController.withModel("javascripts/hello.js", model)

Затем в YourController.withModel вы можете предварительно обработать hello.js (например, использование шаблонов sbt-web плагин) с моделью.

Вы также можете предварительно обработать JS с моделью, прежде чем перейти в этот шаблон Scala HTML.

Если ЦП / память являются серьезной проблемой, это может стать более сложным: например, отображение между заранее определенными моделями и предварительно обработанной статической JS файлы и ссылки на них вместо. Или используйте другие методы кэширования /CDN.

Итак, это всего лишь идеи в дополнение к другим ответам, приведенным здесь. Наслаждаться.

Другие вопросы по тегам