Это неправильный способ обработки Ajax-запроса, поскольку вы нарушаете жизненный цикл страницы CMS за октябрь.
вы получаете сообщение об ошибке, потому что вы напрямую просите компонент обработать запрос Route::get('/planner/{page}', 'myName\budgetplanner\Components\app@test');
как renderpartial
нужен контекст контроллера, и если вы сделаете route
, как это, он обязательно yield unexpected behaviour
Хорошо, мы получим это, НО тогда, Как это сделать правильно?
Ваш URL, скажем, используется таким образом /planner/:type

Добавление фреймворка и дополнения к верному макету для ajax-framework [, убедитесь, что вы добавили их перед вашим скриптом ]
<script src="{{ 'assets/javascript/jquery.js'|theme }}"></script>
{% framework extras %}
Ваш скрипт должен выглядеть следующим образомэто
<script>
$(document).ready(function() {
$(document).on('click','.tile',function() {
let page = $(this).attr('data-tile');
history.pushState({page}, '', '/planner/' + page );
getPage(page);
});
window.onpopstate = function(e){
if(e.state){
getPage(e.state.page);
}
};
// not sure causing issues so commented
// history.replaceState({page: null}, 'Default state', './planner');
function getPage (page) {
$.request('onRenderTile', { data: { type: page }})
}
});
</script>
Ваш компонент
public function onRender()
{
// if type is not passed default would be dashboard
$type = $this->param('type', 'dashboard');
return $this->onRenderTile($type)['#tile-area'];
}
public function onRenderTile($type = null)
{
$availableTiles = [
'dashboard',
'tile1',
'tile2',
'tile3',
];
// if not passed any value then also check post request
if(empty($type)) {
$type = post('type');
}
// we check partial is valid other wise just return dashboard content
if(in_array($type, $availableTiles)) {
return ['#tile-area' => $this->renderPartial('@'.$type.'.htm')];
}
else {
return ['#tile-area' => $this->renderPartial('@dashboard.htm')];
}
}
Ваши двоечники
file: _tiles.htm
<div class="tile" data-tile="dashboard">Dashboard</div>
<div class="tile" data-tile="tile1">Tile 1</div>
<div class="tile" data-tile="tile2">Tile 2</div>
<div class="tile" data-tile="tile3">Tile 3</div>
файл: dashboard.htm
<div id="tile-area">
{% partial __SELF__~"::_tiles" %}
<h1>Dashboard</h1>
</div>
файл: tile1.htm
<div id="tile-area">
{% partial __SELF__~"::_tiles" %}
<h1>Tile 1 Content</h1>
</div>
файл: tile2.htm
<div id="tile-area">
{% partial __SELF__~"::_tiles" %}
<h1>Tile 2 Content</h1>
</div>
файл: tile3.htm
<div id="tile-area">
{% partial __SELF__~"::_tiles" %}
<h1>Tile 3 Content</h1>
</div>
Первоначально он будет отображать default partial dashboard
, если не передано type
dashboard
имеет все остальные tile links
и dashboard content
такие же, как other tile partials
.
Теперь, если вы click any tile
, он будет fire October Ajax framework request
с обработчиком onRenderTile
и type (dashboard|tile1|tile2 ...)
, поэтому он будет правильно вызывать October lifecycle methods
и, наконец, визуализировать частичное с помощью onRenderTile
и вернуть json с ключом #tile-area
, и в качестве значения оно будет return content of posted partial name(type)
OctoberCMS ajax framework
достаточно умным, чтобы просто заменить этот контентс указанием идентификатора, поэтому он будет искать #tile-area
и заменяет свой контент новым.
для получения дополнительной информации об обновлении партиалов с помощью ajax
вы можете прочитать это: https://octobercms.com/docs/ajax/update-partials
если есть сомнения или вопрос, пожалуйста, прокомментируйте.