• урок
  • pantey

Drupal 8 – Создание кастомной Ajax команды

28.06.2017

Продолжаем рассматривать Ajax API в Drupal 8, вы уже знаете, как создать кастомную Ajax ссылку, а так же узнали, какие еще существуют Ajax команды, но на этом возможности Ajax API не заканчиваются.

Очень часто приходится сталкиваться с ситуацией, когда существующих Ajax команд не хватает и связано это, как правило, с использование сторонних библиотек, когда библиотека имеет свой набор команд и свойств.

Сегодня мы рассмотрим, как создавать свою кастомную Ajax команду, естественно весь процесс будет реализован в кастомном модуле, в моем случае он будет называться – custom_ajax_command.

Весь процесс расширения списка Ajax команд, можно разделить на 2 этапа:

  • Определение Ajax команды (название, переменные)
  • Описание Jquery метода, для данной команды

В нашем случае добавится еще пару пунктов:

  • Создание библиотеки, которая будет содержать наш Jquery метод
  • Подключение библиотеки на страницу

Создаем модуль – файл custom_ajax_info.yml

name: 'Custom Ajax Command'
description: 'Простая реализация кастомной Ajax команды'
core: 8.x
type: module
package: 'Other'
version: '8.x-1.0'

Определяем кастомную Ajax команду – файл CustomAjaxCommand.php

<?php

namespace Drupal\custom_ajax_command\Ajax;
use Drupal\Core\Ajax\CommandInterface;

class CustomAjaxCommand implements CommandInterface {

  protected $message;
  # Constructs
  public function __construct($message) {
    $this->message = $message;
  }

  # Implements Drupal\Core\Ajax\CommandInterface:render().
  public function render() {
    return array(
      'command' => 'customAjaxCommand',   // Обязательное свойство - определяет название кастомного Jquery (JS) метода, которая будет запущена
      'message' => $this->message,        // Переменные, которые будут доступны в response
    );
  }
}

Хочу заметить, кто забыл, в Drupal 8 разработка строится по стандарту PSR-4, соответственно все классы должны находится в директории src вашего модуля.

Описываем Jquery метод, для кастомной команды – файл custom_ajax_command.js. Данный файл будет находится в директории js вашего модуля.

(function($, Drupal) {

  if(Drupal.AjaxCommands){

    // Custom Ajax command
    Drupal.AjaxCommands.prototype.customAjaxCommand = function(ajax, response, status){
      alert(response.message);
    }

  }

})(jQuery, Drupal);

Далее, создаем библиотеку, которая будет содержать файл с описанием Jquery метода, нашей Ajax команды.

Файл custom_ajax_command.libraries.yml

# Libraries for Custom Ajax command
custom_ajax_command:
  version: VERSION
  js:
    # Add JS files
    js/custom_ajax_command.js: {}
  dependencies:
    - core/drupal.ajax
    - core/jquery
    - core/jquery.once
    - core/drupal

Теперь нам осталось подключить данную библиотеку на страницы нашего сайта.

Хочу заметить, что мы подключаем данную библиотеку на все страницы сайта только в качестве примера, на своих сайтах всегда подключайте библиотеку только там, где она необходима.

Файл custom_ajax_command.module

<?php

/**
 * @param $variables
 * Implements hook_preprocess_page()
 */
function custom_ajax_command_preprocess_page(&$variables){

  $variables['#attached']['library'][] =  'custom_ajax_command/custom_ajax_command';

  # Add libraries for anonymous
  $logged_in = \Drupal::currentUser()->isAuthenticated();
  if(!$logged_in){
    $libraries['#attached']['library'][] = 'core/drupal.ajax';
  }

  render($libraries);

}

С созданием кастомной Ajax команды мы закончили, теперь вы можете ее использовать в ваших контроллерах

<?php

use Drupal\custom_ajax_command\Ajax\CustomAjaxCommand;

# Custom Ajax command
$message = 'Этот alert() был запущен из кастомной Ajax команды';
$response->addCommand(new CustomAjaxCommand($message));

Скачать модуль используемый в примере

Скачать

-->
Узнавай о новых статьях сайта - первым. Просто подпишись на рассылку.

Комментарии (12)

Profile picture for user Astral
Александр
15.08.2017

1. Подскажите, что за response и где он находится?

'message' => $this->message, // Переменные, которые будут доступны в response

 

2. Почему в этом примере Вы не создавали файла с роутингами?

Profile picture for user pantey
pantey
15.08.2017
  1. response - объект JS, который содержит переданные ему значения, при вызове вашей кастомной AJAX команды
  2. в этом нет необходимости, мы создали только команду, а использовать ее вы можете например, в коде из предыдущих статей - как создать Ajax ссылку
Profile picture for user Astral
Александр
15.08.2017

3. В какой файл этот код вставлять?

# Custom Ajax command
$message = 'Этот alert() был запущен из кастомной Ajax команды';
$response->addCommand(new CustomAjaxCommand($message));
Profile picture for user pantey
pantey
15.08.2017

написал выше - как создать Ajax ссылку, данный модуль создает лишь команду, а где ее использовать вам решать.

Profile picture for user Astral
Александр
16.08.2017

1. И еще вопрос, что означает данная строка Drupal.AjaxCommands.prototype.customAjaxCommand = function ... ??

раньше встречал только такую запись  Drupal.behaviors.MyBehaviour = function ...

 

2. Тут alert(response.message); response - это объект, а message данные которые в него передаются?

Profile picture for user pantey
pantey
16.08.2017

 По пунктам:

  • Drupal.AjaxCommands.prototype.customAjaxCommand - определяет функцию в момент вызова кастомной Ajax команды
  • Drupal.behaviors.MyBehaviour - определяет обычную JS функцию
  • message  - название переменной, которую вы определили в вашей Ajax команде, а значение этой переменной будет содержаться в объекте response.message
Profile picture for user Astral
Александр
16.08.2017

Я скачал Ваш модуль, добавил контроллер и роутинг.

<?php
 
namespace Drupal\custom_ajax_command\Controller;

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\AlertCommand;
use Drupal\Core\Ajax\CommandInterface;
 
class AjaxController {

  public function ajaxcon {

    $response = new AjaxResponse($message);

$message = 'Этот alert() был запущен из кастомной Ajax команды';
$response->addCommand(new CustomAjaxCommand($message));

    # Return response
    return $response;
  }
}

 

Но при установке модуля появляется ошибка ReflectionException: Class \Drupal\custom_ajax_command\Controller\AjaxController does not exist in ReflectionMethod->__construct() (line 123 of /var/www/test.loc/core/lib/Drupal/Core/Entity/EntityResolverManager.php).

Подскажите в чем проблема?

Profile picture for user pantey
pantey
17.08.2017

Возможно, причина в том, что не отнаследовались.

Покажите роутинг

<?php

class AjaxController extends ControllerBase{

# Здесь ваш response

}

 

Profile picture for user Astral
Александр
18.08.2017

Я роутинг Ваш скачал:

custom_ajax_command.routing:
  path: '/ajax'
  defaults:
    _title: 'Custom Ajax Link'
    _controller: '\Drupal\custom_ajax_command\Controller\AjaxController::ajaxcon'
  requirements:
    _permission: 'access content'

Profile picture for user Astral
Александр
21.08.2017

Извините за дезинформацию, я роутинг сам создавал

Profile picture for user pantey
pantey
21.08.2017

так заработало или нет ? Если нет, то кидайте ваш модуль мне на почту - я гляну.

Profile picture for user Astral
Sergey
30.12.2017

Сначала тоже не получалось, но потом докапался, нужно в контроллере использовать класс с созданной командой:

use Drupal\custom_ajax_command\Ajax\CustomAjaxCommand;