#angularjs #rest #cakephp #cakephp-2.0 #ionic-framework
#angularjs #rest #cakephp #cakephp-2.0 #ionic-framework
Вопрос:
Я кодирую клиент-серверное приложение.
- Серверная часть работает на CakePHP 2.4.7.
- Запуск на стороне клиента с angularjs и cordova на мобильных устройствах
Я использую несколько префиксов маршрута cakephp, у которых ‘admin’ и ‘mobile’. (И я использую фабрики angularjs $resource и $ HttpInterceptor для настройки своих запросов REST.)
Я хочу вызвать /website/mobile/posts/add.json
с помощью отправки данных в формате json.
Итак, я вызываю /website/mobile/posts.json
запрос POST ajax:
Проблема здесь: вызываемое действие контроллера — это «индекс», а не «добавить»;
Поверх моего PostsController я добавил это:
echo $this->request->params['action'] . "n";
echo ($this->request->isPost())? "post" . "n" : "not post";
die;
и ответ всегда:
mobile_index
post
Таким образом, запрос ajax кажется правильным, но cakephp не сопоставляет его с действием add, а индексирует его.
Однако моя конфигурация тоже кажется хорошей; вот фрагмент моего routes.php
Router::mapResources(array('users','posts'));
Router::parseExtensions('json');
Есть идеи?
Комментарии:
1. Используете ли вы фактическую префиксную маршрутизацию (
Configure::write('Routing.prefixes', /*...*/)
), т. Е. Вы хотите в конечном итоге вызывать префиксные действия контроллера, напримерmobile_add()
, или ваши «префиксы» просто красивые URL-адреса?2. Да, я действительно использую префиксную маршрутизацию
Ответ №1:
Префиксная маршрутизация не работает с REST-маршрутизацией из коробки
Маршрутизация REST работает путем автоматического создания маршрутов для переданных контроллеров Router::mapResources()
. Префиксная маршрутизация в значительной степени делает то же самое, она создает маршруты по умолчанию, включая префиксы, определенные в Routing.prefixes
.
Однако обе функции не знают друг о друге, они оба создают отдельные маршруты, поэтому Router::mapResources()
будут подключаться к URL-адресам без префиксов ( prefix
опция для этого метода не использует фактическую маршрутизацию префиксов, она просто добавит значение этой опции в начало URL-адреса для подключения!), И, следовательно, вашзапрос на /mobile/...
самом деле не использует маршрутизацию REST, а только маршрутизацию с префиксом.
Определение маршрутов REST с префиксами вручную
Для этой проблемы нет простого решения, такого как использование опции или чего-то еще, вместо этого вам придется определять маршруты REST вручную, чтобы включить опцию prefix, хотя это достаточно просто.
См. Изменение маршрутов REST по умолчанию и Пользовательская маршрутизация REST.
Примерный маршрут может выглядеть следующим образом:
Router::connect(
'/mobile/users',
array(
'prefix' => 'mobile',
'mobile' => true,
'controller' => 'users',
'action' => 'add',
'[method]' => 'POST'
)
);
Это будет подключать запросы POST к /mobile/users
to UsersController::mobile_add()
. Аналогично, вам нужно будет сделать это для всех других методов, таких как GET
and PUT
, с передачей и без передачи id
и т. Д.
Обратите внимание, что при подключении вручную вы можете отказаться от Routing.prefixes
опции и, конечно, вызова Router::mapResources()
.
Автоматическое сопоставление
Определение всех этих маршрутов вручную довольно утомительно, вам лучше автоматизировать его в зависимости от Router::resourceMap()
конфигурации.
Вот пример того, как это сделать, он чем-то похож на Router::mapResources()
, но он принимает prefix
опцию, которая фактически использует префиксную маршрутизацию:
function mapResources(array $controllers) {
$resourceMap = Router::resourceMap();
foreach($controllers as $controller => $options) {
if(!is_array($options)) {
$controller = $options;
$options = array();
}
$options = array(
'prefix' => null,
'plugin' => null,
'id' => Router::ID . '|' . Router::UUID
);
foreach($resourceMap as $params) {
$url = '';
if($options['prefix']) {
$url .= '/' . $options['prefix'];
}
if($options['plugin']) {
$url .= '/' . $options['plugin'];
}
$url .= '/' . $controller;
if($params['id']) {
$url .= '/:id';
}
Router::connect(
$url,
array(
'prefix' => $options['prefix'],
$options['prefix'] => !!$options['prefix'],
'plugin' => $options['plugin'],
'controller' => $controller,
'action' => $params['action'],
'[method]' => $params['method']
),
array(
'id' => $options['id'],
'pass' => array('id')
)
);
}
}
}
Вы бы назвали это так:
mapResources(array(
'books' => array(
'prefix' => 'mobile'
)
));
и это сопоставило бы все маршруты REST для вашего books
контроллера с использованием mobile
префикса.