После прочтения статьи "Порог вхождения в Angular 2 — теория и практика" у меня появилось желание показать, как можно пробросить все роуты Angular 2 через роутер Laravel 5.
Идея следующая
- в директории
resources/views/backend
будет лежать представление, являющееся точкой входа для всех роутов Angular 2. Для каждого роута Angular 2, роутер Laravel 5 будет нас перенаправлять на это представление; - под каждый Angular 2 роут в директиве
@RouteConfig
нам придется создать копию в роутере Laravel; - все роуты Angular 2, по которым подтягиваются шаблоны, будут иметь вид вида
/templates/SomeComponent.main
, и будут запрашиваться роутером Laravel 5 по пути видаresources/views/frontend/SomeComponent/main.blade.php
Приступим
Чтобы не запутаться, разобьем все представления в директории resources/views
на 2 подпапки:
backend
— для представлений, которые Laravel 5 использует напрямую;frontend
(в статье будет использоватьсяfrontend
, но кто-то пожелает переименовать, например вtemplates
) — для всех шаблонов, которые будут использоваться в Angular 2.
1) Front-end
Допустим, у нас есть уже созданный root-компонент app.component.ts
, а так же 2 компонента: components/MainComponent.ts
, который будет загружаться по умолчанию, и components/EditComponent.ts
.
Мы хотим указать в директиве @RouteConfig
2 роута: один '/' с именем Home
, ведущий на MainComponent
, а второй '/edit' с именем Edit
, ведущий на EditComponent
.
//app.component.ts
@RouteConfig([
{
path: '/',
name: 'Home,
component: MainComponent,
useAsDefault: true
},
{
path: '/edit',
name: 'Edit',
component: EditComponent
}
])
@Component({
'directives': [ROUTER_DIRECTIVES],
'selector': 'app',
'template': '<router-outlet></router-outlet>'
})
export class AppComponent {
constructor () {}
}
Далее необходимо задать для компонентов их шаблоны:
//components/MainComponent.ts
@Component({
'selector': 'state-template',
'templateUrl': '/templates/MainComponent.main'
})
export class MainComponent {
...
}
//components/EditComponent.ts
@Component({
'selector': 'state-template',
'templateUrl': '/templates/EditComponent.main'
})
export class EditComponent {
...
}
2) Back-end
Первым делом, в роутере Laravel 5 продублируем все основные роуты Angular 2. Все подобные роуты мы будем направлять в AngularRoutesController
.
//routes.php
Route::get('/', [
'uses' => 'MyAppAngularRoutesController@index',
'as' => 'ngHome'
]);
Route::get('/edit', [
'uses' => 'MyAppAngularRoutesController@index',
'as' => 'ngEdit'
]);
В AngularRoutesController
мы будем просто рендерить представление, являющееся точкой входа, для Angular 2:
public function index()
{
return view('backend.content');
}
Представление views/backend/content.blade.php
должно содержать в себе тег, в который будет грузиться Angular 2 приложение, у нас это app
.
@extends('backend.layout')
@section('backend.content')
<app>
@include('backend.loading')
</app>
@include('backend.scripts-import')
@stop
Для роутов Angular 2, ведущих к темплейтам, создадим еще 1 Laravel 5 маршрут, который будет перенаправлять запрос на контроллер AngularTemplatesController
:
//routes.php
Route::get('/templates/{template}', [
'uses' => 'MyAppAngularTemplatesController@index',
'as' => 'ngTemplates'
]);
Внутри AngularTemplatesController
нам необходимо добавить к $template
, в котором содержится часть пути к представлению с шаблоном, имя нашей папки с шаблонами Angular 2 — frontend
.
public function index($template)
{
$templatePath = 'frontend.' . $template;
if (!view()->exists($templatePath)) {
throw new NotFoundHttpException();
}
return view($templatePath);
}
Итог
В результате, все Angular 2 шаблоны, которые будут запрашиваться по URL-адресу вида /templates/SomeComponent.main
будут браться по пути вида resources/views/frontend/SomeComponent/main.blade.php
. Мы сможем использовать шаблонизатор Blade в шаблонах Angular 2.
Нюансы
Поскольку в шаблонизаторе Blade и в шаблонах Angular 2 используется одинаковый синтаксис с двойными фигурными скобками {{ ... }}
, для корректной обработки двойных фигурных скобок, относящихся к Angular 2, необходимо будет ставить перед ними символ @
.
Этот символ позволит шаблонизатору Blade игнорировать такие конструкции, для последующего из разбора Angular 2.
<div>{{ bladeVariable }}</div>
<li *ngFor="#file of files" class="list-group-item">
@{{ file.name }}
</li>
Репозиторий с примером.
Автор: sanex3339