Điểm:0

Tôi nên sử dụng hook_cache_flush() hoặc hook_rebuild() như thế nào trong một mô-đun tùy chỉnh để thực thi mã JavaScript khi bộ nhớ cache bị xóa?

lá cờ jp

Tôi đang cố gắng tạo một mô-đun thực thi một số mã JavaScript khi bộ đệm ẩn bị xóa (thông qua menu quản trị viên hoặc cách khác). Tôi tin rằng tôi có thể thực hiện một trong hai hook_cache_flush() hoặc hook_rebuild(), nhưng tôi không hoàn toàn chắc chắn làm thế nào. Tôi không nhất thiết phải tìm kiếm điều này được thực hiện cho mình, nhưng nếu tôi có thể được đưa ra một điểm xuất phát và hướng đi để bắt đầu, điều đó thật tuyệt.

Điểm:1
lá cờ us

Không hook_cache_flush() cũng không hook_rebuild() việc triển khai có thể trực tiếp thêm mã JavaScript vào một trang, đơn giản vì thực tế là chúng không lấy bất kỳ mảng kết xuất nào làm đối số, cũng như không trả về mảng kết xuất cho hàm/phương thức gọi chúng. Bạn có thể thêm trình xử lý gửi biểu mẫu vào system_performance_settings hình thức cho khi Xóa tất cả bộ đệm nút trên biểu mẫu đó được nhấp. Điều này sẽ không hoạt động khi xóa bộ đệm bằng các phương pháp khác, chẳng hạn như bằng một mô-đun gọi drupal_flush_all_caches() trong mã của nó.

// Đặt dòng sau vào đầu tệp chứa mã này.
sử dụng Drupal\Core\Form\FormStateInterface;

function mymodule_form_system_performance_settings_alter(&$form, FormStateInterface $form_state) {
  if (isset($form['clear_cache']['clear'])) {
    if ($form_state->getTemporaryValue('mymodule_cache_cleared')) {
      $form['#attached']['library'][] = 'mymodule/cache.rebuild';
    }
    $form['clear_cache']['clear']['#submit'][] = 'mymodule_system_performance_settings_submit';
  }
}

function mymodule_system_performance_settings_submit(mảng &$form, FormStateInterface $form_state) {
  $form_state->setRebuild();
  $form_state->setTemporaryValue('mymodule_cache_cleared', TRUE);
}

Đối với một giải pháp hoạt động trong mọi trường hợp drupal_flush_all_caches() được gọi và thêm mã JavaScript vào trang đầu tiên được yêu cầu sau khi xóa bộ nhớ cache, tôi sẽ triển khai hook_cache_flush() để đặt một giá trị mà sau đó được đăng ký hook_page_attachments().

hàm mymodule_cache_flush() {
  \Drupal::state()->set('mymodule_cache_cleared', TRUE);
}

function mymodule_page_attachments(mảng &$attachments) {
  $state = \Drupal::state();
  if ($state->get('mymodule_cache_cleared')) {
    // Xóa giá trị trạng thái để tránh thư viện được thêm vào
    // mọi trang sau khi xóa bộ nhớ cache.
    $state->delete('mymodule_cache_cleared');

    $attachments['#attached']['library'][] = 'mymodule/cache.rebuild';
  }
}

Để thêm mã JavaScript vào đầu tiên X các trang được yêu cầu sau khi xóa bộ đệm, tôi sẽ sử dụng các triển khai hook sau đây. (Mã sau đính kèm thư viện vào ba yêu cầu trang đầu tiên.)

hàm mymodule_cache_flush() {
  \Drupal::state()->set('mymodule_cache_cleared_count', 3);
}

function mymodule_page_attachments(mảng &$attachments) {
  $state = \Drupal::state();
  if ($count = $state->get('mymodule_cache_cleared_count')) {
    $attachments['#attached']['library'][] = 'mymodule/cache.rebuild';
    $state->set('mymodule_cache_cleared_count', $count - 1);
  }
}

tôi đã sử dụng \Drupal::state()->get()\Drupal::state()->set() bởi vì:

  • Giá trị được đặt với drupal_static() sẽ không được bảo tồn giữa các yêu cầu trang. Trang tài liệu nói rõ ràng:

    Tất cả các chức năng yêu cầu một biến tĩnh để duy trì hoặc lưu trữ dữ liệu trong một yêu cầu trang duy nhất được khuyến khích sử dụng chức năng này trừ khi hoàn toàn chắc chắn rằng biến tĩnh sẽ không cần phải đặt lại trong khi yêu cầu trang.

  • Đặt giá trị phiên, mỗi người dùng sẽ nhận được một giá trị khác nhau. Điều này có nghĩa là mã JavaScript sẽ được thêm vào trang tiếp theo được yêu cầu sau khi xóa bộ nhớ cache chỉ khi trang đó được yêu cầu từ cùng một người dùng đã đăng nhập khi bộ nhớ cache đã bị xóa.

Thêm JavaScript vào Chủ đề hoặc Mô-đun của bạn cho biết cách một thư viện JavaScript được xác định từ một mô-đun.

lá cờ jp
Tôi muốn sử dụng một trong những chức năng tôi đã liệt kê để mã sẽ thực thi mỗi khi một trong những chức năng đó được gọi. Theo cách đó, vâng, nút trong cài đặt hiệu suất sẽ làm điều đó, nhưng nếu ai đó đã cài đặt mô-đun menu quản trị và xóa bộ nhớ cache của họ theo cách đó, nó vẫn sẽ thực thi. Không có cách nào để thực thi JS khi một hook nhất định được sử dụng, bất kể đối số của nó là gì hoặc nó trả về cái gì?
apaderno avatar
lá cờ us
Móc duy nhất có thể thay đổi mảng kết xuất cho một trang sẽ được gọi cho mọi trang và nó sẽ không thể hiểu liệu bộ nhớ cache có bị xóa hay không.
lá cờ jp
Tôi biết bạn đang nói về cái móc nào và bạn đã đúng. Đối với JS, tôi sẽ không hỏi cách thực hiện những gì tôi đặc biệt muốn làm, nhưng nếu tôi muốn thêm một cái gì đó đơn giản như cảnh báo chỉ để kiểm tra thư viện của mình, bạn có thể cho tôi gợi ý về cách thực hiện không điều đó? Tôi đã đọc qua tài liệu bạn đã liên kết và không tìm thấy giải pháp nào phù hợp với mình.
lá cờ cn
Bạn luôn có thể đặt một var tĩnh trong hook và chọn lại nó trong `hook_pre process_page()` (xem [`drupal_static()`](https://api.drupal.org/api/drupal/core%21includes%21bootstrap .inc/function/drupal_static/9.3.x) để mẫu sử dụng). Nhưng nó sẽ không hoạt động trong mọi ngữ cảnh; ví dụ: khi bạn xóa bộ nhớ cache khỏi menu quản trị, nó sẽ chuyển hướng trở lại trang xuất phát, vì vậy bạn không có cơ hội đính kèm thư viện vào trang. Bạn có thể giải quyết vấn đề đó bằng cách sử dụng phiên hoặc lưu trữ tạm thời, nhưng sẽ tốn nhiều công sức hơn và có thể trở nên lộn xộn nếu chuyển hướng trang không thành công chẳng hạn
4uk4 avatar
lá cờ cn
@Clive, đó là một ý tưởng hay khi đặt giá trị phiên, giống như bạn có thể đặt thông báo cho lần tải toàn trang tiếp theo.Tuy nhiên, để đọc và xóa giá trị phiên này, bạn không thể sử dụng hook tiền xử lý trang, các trang được lưu trong bộ nhớ cache. Bạn có thể sử dụng người đăng ký sự kiện phản hồi sau khi trang được truy xuất từ ​​bộ đệm hoặc khối không thể lưu vào bộ đệm với tuổi tối đa của bộ đệm là 0, khối này luôn được lưu vào bộ đệm dưới dạng trình giữ chỗ và chạy trên mọi yêu cầu trang.
apaderno avatar
lá cờ us
@Joseph Tôi đã thêm một giải pháp nữa, vì những gì được báo cáo trong các nhận xét không hoàn toàn chính xác.
apaderno avatar
lá cờ us
@ 4uk4 Sẽ ​​là một ý tưởng hay nếu OP cần một giá trị khác nhau cho mỗi người dùng. Nếu OP cần đặt giá trị khi xóa bộ đệm và sử dụng giá trị đó để thêm mã JavaScript vào trang bắt buộc tiếp theo, độc lập với người dùng truy cập trang đó, thì phiên đó không thể sử dụng được.
4uk4 avatar
lá cờ cn
OK, nhưng xóa bộ đệm trong yêu cầu bài đăng chuyển hướng trực tiếp đến tải trang bình thường (tất nhiên là với cùng một cookie phiên) là trường hợp sử dụng drupal_flush_all_caches() có khả năng nhất theo tài liệu. Nếu có một trình duyệt liên quan. Nếu không thì javascript không có nhiều ý nghĩa.
apaderno avatar
lá cờ us
@ 4uk4 Tôi không hiểu mục đích của việc chạy mã JavaScript khi bộ đệm Drupal bị xóa là gì. Tôi nghĩ rằng OP đang cố gắng thay đổi điều gì đó ở cấp trình duyệt, nhưng đây chỉ là một dự đoán hoang dã. Đó là lý do tại sao tôi tránh nói bất cứ điều gì về việc sử dụng JavaScript là ý tưởng tốt hay xấu.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.