六月 7, 2019 | 前端與Vue

【D8 教學】消失的drupal_add_js,該如何傳遞變數到前端

在D7,當前後端要進行傳值溝通的時候,我們很常使用的手法就是使用drupal_add_js這個函數。不僅可以幫助我們加入想要的library,還可以決定順序甚至傳值。幾乎所有大模組像是Better Exposed Filter、Custom Search、admin menu都是使用這種手法。而到了D8,drupal_add_js這個變數已經不復存在,那麼該如何來處理同樣的效果呢

前言

在D7,當前後端要進行傳值溝通的時候,我們很常使用的手法就是使用drupal_add_js這個函數。不僅可以幫助我們加入想要的library,還可以決定順序甚至傳值。幾乎所有大模組像是Better Exposed Filter、Custom Search、admin menu都是使用這種手法。而到了D8,drupal_add_js這個變數已經不復存在,那麼該如何來處理同樣的效果呢

如何從後端傳值到前端

傳值在這裡的意思是,後端如果要傳值(可能是變數、陣列、物件)到前端,讓JS可以直接抓取使用。以下範例我會用把一個陣列傳到前端作為例子。

首先溫故知新一下D7的方法,若有需要的朋友,可以直接拿去用囉。當然官方有詳細的說明,若不想直接看我寫的,也可以進官方網站進行查詢。

D7 版本

若會建立custom module,即可以把以下的程式碼放在你想要執行的任何一個邏輯裡面。

<?php

/**
 *  Implements hook_init() 
 *  寫在這裡是讓每一個頁面都會有接到傳值,但視自己需求而定
 **/
function mymodule_init(){
  //以下是我們想要傳出去的值
  $data = array(
    'data1' => 'first-data',
    'data2' => 'second-data'
  );
  
  //傳到前端
  drupal_add_js(array('myPassingVariable' => $data,), 'setting');
  
}
?>

寫完以後,就可以直接使用js來抓取到對應的變數,以下在Chrome的Console裡面,寫入Drupal.settings,即可發現眾多的變數都是存在drupal.settings的物件裡面,可以讓JS直接使用囉。

D8 版本

而到了D8,將不再使用drupal_add_js,取而代之則是使用 *.libraries.yml file 宣告後,再自行加入。

D8與D7在處理JS上面有兩個很大的差異

  1. Drupal只有在需要的頁面,才會加入JS Library,原生Drupal呈現給匿名使用者網頁時,不再需要JS了,也就是說jQuery不會再自動加入到每一個頁面,所以當某些狀況下需要jQuery,則需要自行宣告並加入。
  2. D7的Drupal.settings JS物件被改成 drupalSettings 的物件

mymodule.libraries.yml

my_customjs:
  version: 1.x
  js:
    js/customjs.js: {}
  dependencies:
    - core/jquery
    - core/drupalSettings

一樣再想要傳值的函數內補上下面語法,即可傳到前端

$data = [
  'data1' => 'first-data',
  'data2' => 'second-data'
];

$build['#attached']['library'][] = 'mymodule/my_customjs';
$build['#attached']['drupalSettings']['myPassingVariable'] =$data;

通過 drupalSettings 即可看到全部傳到前端的物件變數,當然,以目前範例來說,可以通過drupalSettings.myPassingVariable 即可得到對應的陣列。

小記

目前在越來越往前後端分離趨勢走的情況下,數值間的溝通變得非常重要。而在使用Progressive Decouple架構下,更覺得可以把Drupal的彈性與前端框架的彈性發揮到極致。這種傳值的作法將會變得很重要。D7與D8有極大的差異,D7方便,但D8更為嚴謹、彈性更足。給需要的人參考囉~