Подтвердить что ты не робот

Play Framework 2.1 - AngularJS routing - лучшее решение?

Я работаю над учебником AngularJS. Angular использует собственный механизм маршрутизации JS, позволяющий использовать одностраничные приложения. Пример файла маршрутизации для Angular выглядит следующим образом:

angular.module('phonecat', []).
  config(['$routeProvider', function($routeProvider) {
  $routeProvider.
      when('/phones', {templateUrl: '/partials/phone-list',   controller: PhoneListCtrl}).
      when('/phones/:phoneId', {templateUrl: 'partials/phone-detail', controller: PhoneDetailCtrl}).
      otherwise({redirectTo: '/phones'});
}]);

Я пытаюсь найти хорошее место для хранения моих частичных (Angular конкретных HTML файлов). В идеале мне хотелось бы сфокусировать их в Play (т.е. Иметь их как *.scala.html файлы). Я могу выполнить это, используя файл Play Play, например:

GET     /partials/phone_index       controllers.Application.phone_index

Я в основном частично/к действию контроллера следующим образом:

def phone_index = Action {
  Ok(views.html.partials.phone_index())
}

Решение, которое я ищу, представляет собой комбинацию двух идеалов:

  • У меня будет какое-то сопоставление, которое позволяет мне посещать любой файл под /partial/ * и возвращать частичный файл.
  • Я хотел бы переопределить маршрут к определенной части, чтобы я CAN использовал действие контроллера для динамического заполнения данными (редко).

Любые идеи?

4b9b3361

Ответ 1

Когда я пытался что-то подобное, я пришел к выводу, что лучше разбить его на 2 части:

  • Используйте Play в качестве бэкэнд, с которым вы взаимодействуете с помощью вызовов Ajax.
  • Сохраните шаблоны Angular в папке Play public (что-то вроде /public/angular/) и используйте метод AngularJs по умолчанию для сопоставления шаблонов

Я знаю, что это не здорово и на самом деле не отвечает на ваш вопрос о том, как это сделать, но попытка связать обе структуры может быть проблематичной из-за того, как шаблоны и их URL отображаются в Angular, и польза будет очень мала, так как любое изменение будет означать большую работу, тем самым устраняя, возможно, основное преимущество как Play, так и Angular, быстрого развития.

Это также позволяет вам лучше отделять проблемы, которые, если ваш проект растет, могут быть важны, поскольку вы можете просто удалить код AngularJS в качестве автономного приложения, подключающегося к бэкэнд, и оно будет работать нормально.

В этом репозитории Github вы можете увидеть пример кода, который я сказал (на основе учебника TODO для AngularJS). Я предупреждаю вас, код не слишком приятный, но должен дать вам представление, и в качестве бонуса вы узнаете, как интегрировать Jasmine в Play, для модульного тестирования AngularJS.

Ответ 2

Возможное семя (https://github.com/angyjoe/eventual) - еще один способ создания приложения Play + AngularJS. Код является возлюбленным и хорошо документирован.

Ответ 3

Это не будет отвечать на ваш вопрос напрямую, но я нашел, что это лучший способ создать Play + Angular apps:

https://github.com/typesafehub/angular-seed-play

Ответ 4

Да, возможно создать серверные мета-шаблоны клиентских шаблонов. Это дает некоторые уникальные способности, так как эти два метода не перекрываются полностью. Там также много места для путаницы, поэтому убедитесь, что знаете, почему вы пишете блок Play вместо директивы Angular.

Нужно ли вам это делать, остается открытым вопрос; это действительно зависит от того, действительно ли вам нужен доступ к информации о сервере в ваших шаблонах. Пример того, где, по моему мнению, было бы необходимо и целесообразно было бы реализовать контроль доступа в ваших представлениях.

Теперь, чтобы ответить на ваш вопрос. Проблема решается путем вложения частичных данных вместо того, чтобы пытаться обеспечить маршрут для их загрузки по требованию. См. http://docs.angularjs.org/api/ng.directive:script.

Вот как выглядит шаблон:

@(id: Long)(implicit request: RequestWithUser[AnyContent])

@import helper._

<!doctype html>
<html lang="en" ng-app="phonecat">
<head>
  <meta charset="utf-8">
  <title>Google Phone Gallery</title>
  <link rel="stylesheet" href="css/app.css">
  <link rel="stylesheet" href="css/bootstrap.css">
  <script src="lib/angular/angular.js"></script>
  <script src="js/app.js"></script>
  <script src="js/controllers.js"></script>
  <script src="js/filters.js"></script>
  <script src="js/services.js"></script>
  <script src="lib/angular/angular-resource.js"></script>
</head>
<body>
  <div ng-view></div>

  @ngTemplate("phone-list.html") {
    <div class="container-fluid">
      <div class="row-fluid">
        <div class="span12">Hello @request.user.name</div>
      </div>

      <div class="row-fluid">
        <div class="span2">
          <!--Sidebar content-->

          Search: <input ng-model="query">
          Sort by:
          <select ng-model="orderProp">
            <option value="name">Alphabetical</option>
            <option value="age">Newest</option>
          </select>

        </div>
        <div class="span10">
          <!--Body content-->

          <ul class="phones">
            <li ng-repeat="phone in phones | filter:query | orderBy:orderProp" class="thumbnail">
              <a href="#/phones/{{phone.id}}" class="thumb"><img ng-src="{{phone.imageUrl}}"></a>
              <a href="#/phones/{{phone.id}}">{{phone.name}}</a>
              <p>{{phone.snippet}}</p>
            </li>
          </ul>

        </div>
      </div>
    </div>
  }

  @ngTemplate("phone-detail.html") {
    <img ng-src="{{mainImageUrl}}" class="phone">

    <h1>{{phone.name}}</h1>

    <p>{{phone.description}}</p>

    <ul class="phone-thumbs">
      <li ng-repeat="img in phone.images">
        <img ng-src="{{img}}" ng-click="setImage(img)">
      </li>
    </ul>

    <ul class="specs">
      <li>
        <span>Availability and Networks</span>
        <dl>
          <dt>Availability</dt>
          <dd ng-repeat="availability in phone.availability">{{availability}}</dd>
        </dl>
      </li>
    </ul>
  }
</body>
</html>

И приложение:

'use strict';

/* App Module */

angular.module('phonecat', ['phonecatFilters', 'phonecatServices']).
  config(['$routeProvider', function($routeProvider) {
  $routeProvider.
      when('/phones', {templateUrl: 'phone-list.html',   controller: PhoneListCtrl}).
      when('/phones/:phoneId', {templateUrl: 'phone-detail.html', controller: PhoneDetailCtrl}).
      otherwise({redirectTo: '/phones'});
}]);

Просто включите этот помощник:

@**
 * @ngTemplate
 * Generate an AngularJS inlined template.
 *
 * Note: Do not include scripts in your @template HTML. This will break the template.
 *
 * @param name
 * @param template
 *@
@(name: String)(template: Html)

<script type="text/ng-template" id="@name">@template</script>

И обязательно используйте его в корневой области вашего приложения Angular.

Ответ 5

На вопрос №1 вы можете ввести такой маршрут:

/partials/:view    controllers.Application.showView(view:String)

Затем в вашем контроллере вам нужно будет отобразить из имени вида в фактический вид:

Map("phone_index" -> views.html.partials.phone_index())

Возможно, вы захотите отобразить шаблоны ленивыми или потребовать, чтобы запрос присутствовал, тогда вы, вероятно, должны сделать что-то вроде этого:

val routes = Map(
  "phone_index" -> { implicit r:RequestHeader => 
     views.html.partials.phone_index()) 
  }

Ваше действие будет выглядеть примерно так:

def showView(view:String) = 
  Action { implicit r =>
    routes(view)
  }

Если вам нужен определенный метод контроллера для определенного маршрута (вопрос № 2), вы просто добавите маршрут выше динамического:

/partials/specific    controllers.Application.specific()

Ответ 6

Я действительно думаю, что это не очень хорошая идея, даже если она исходит из уважаемого ума.

Я думаю, что очень хорошая практика оставить все мысли как дефолт (соглашение по принципу конфигурации), что означает для меня, что у нас, вероятно, больше интерес к тому, чтобы каждый парадигмы (Play и AngularJS) были разделены, поскольку один или оба могли развиваться в ближайшее или далекое будущее, которое будет стоить для обслуживания кода.

Второй очень важный момент - тестируемость, если вы смешаете оба техноса, вы получите микс, чтобы придумать хороший анализ тестов на обеих сторонах вашего приложения. Приветствия