Score:1

วิธีทำให้แคช Breadcrumbs ไม่ถูกต้องสำหรับโหนดย่อยบน graphQl

ธง gb

ฉันมีตัวอย่างเช่น โหนด A ด้วยนามแฝง โหนด-ก และ โหนด B ด้วยนามแฝง โหนด-a/node-b ของฉัน โหนด B ฉันมีเกล็ดขนมปังนี้ หน้าแรก > โหนด A > โหนด B

ผลลัพธ์ GraphQl:

"เกล็ดขนมปัง": [
                {
                    "ข้อความ": "หน้าแรก",
                    "url": {
                        "เส้นทาง": "/",
                        "กำหนดเส้นทาง": จริง
                    }
                },
                {
                    "ข้อความ": "โหนด A",
                    "url": {
                        "เส้นทาง": "http://example.com/node-a",
                        "กำหนดเส้นทาง": จริง
                    }
                },
                {
                    "ข้อความ": "โหนด B",
                    "url": {
                        "เส้นทาง": "",
                        "กำหนดเส้นทาง": จริง
                    }
                }
            ]

แต่เมื่อฉันเปลี่ยนไป โหนด A ชื่อ ฉันได้รับผลลัพธ์เหมือนเดิมเสมอ (breadcrumbs ไม่เปลี่ยนแปลง) แต่เมื่อฉันบันทึกใหม่ โหนด A หรือล้างแคชการเปลี่ยนแปลงผลลัพธ์ของ graphQl

นี่คือสิ่งที่ฉันได้ลอง:

  1. ล้างแคชของ graphQl (ผลลัพธ์และคำจำกัดความ) ในการอัปเดตโหนด:

     /**
     * ใช้ hook_ENTITY_TYPE_update()
     */
    ฟังก์ชัน MYMODULE_node_update (EntityInterface $entity) {
      // ล้างแคชของ graphql
      /** @var \Drupal\Core\Cache\CacheBackendInterface $graphql_results_cache */
      $graphql_results_cache = \Drupal::service('cache.graphql.results');
      $graphql_results_cache->invalidateAll();
      /** @var \Drupal\Core\Cache\CacheBackendInterface $graphql_definitions_cache */
      $graphql_definitions_cache = \Drupal::service('cache.graphql.definitions');
      $graphql_definitions_cache->invalidateAll();
    }

มันไม่ทำงาน !

  1. ล้างแคชของโหนดลูกทั้งหมดในการอัปเดตโหนดดังนี้:

    /**
     * ใช้ hook_ENTITY_TYPE_update()
     */
    ฟังก์ชัน MYMODULE_node_update (EntityInterface $entity) {
      $database = \Drupal::database();
      // รับนามแฝงเส้นทางโหนดปัจจุบัน
      $alias = \Drupal::service('path_alias.manager')
        ->getAliasByPath('/node/' . $entity->id());
      // รับโหนดลูกทั้งหมดของโหนดปัจจุบัน
      $child_nodes_alias = $database->select('path_alias', 'pa')->fields('pa', [
        'เส้นทาง',
        'นามแฝง',
      ])->เงื่อนไข ('เส้นทาง', '/โหนด/%', 'ชอบ')
        ->เงื่อนไข('นามแฝง', $นามแฝง '%', 'ชอบ')
        ->ดำเนินการ ()
        ->ดึงข้อมูลทั้งหมด ();
      // ทำให้แคชใช้ไม่ได้สำหรับแต่ละโหนดย่อยของโหนดปัจจุบัน
      foreach ($child_nodes_alias เป็น $alias_data) {
        $nid = ระเบิด ('/', $alias_data->เส้นทาง)[2] ?? โมฆะ;
        ถ้า ($nid && $nid != $entity->id()) {
          $tags = ['โหนด:' $นิด];
          แคช::invalidateTags($tags);
          \Drupal::entityTypeManager()->getStorage('node')->resetCache([$nid]);
        }
      }
    }

มันใช้งานไม่ได้เช่นกัน

  1. ฉันรวมสองวิธีก่อนหน้านี้เข้าด้วยกันก็ไม่ได้ผลเช่นกัน

เมื่อฉันล้างแคชทั้งหมดในการอัปเดตโหนด มันใช้งานได้ แต่ไม่ใช่วิธีที่ดีที่สุดที่จะส่งผลกระทบต่อแคชของไซต์


/**
 * ใช้ hook_ENTITY_TYPE_update()
 */
ฟังก์ชัน MYMODULE_node_update (EntityInterface $entity) {
  drupal_flush_all_caches();
}

วิธีที่ดีที่สุดในการล้างแคชเบรดครัมบ์หรือโหนดย่อยโดยไม่ต้องล้างแคชของไซต์ทั้งหมดคืออะไร

แก้ไข: ขอขอบคุณ @4K4 สำหรับความคิดเห็นของคุณ ฉันพยายามเพิ่ม CacheTags ด้วย breadcrumb แต่ก็ไม่ได้ผลเช่นกัน !


/**
 * ใช้ hook_system_breadcrumb_alter()
 */
ฟังก์ชัน MYMODULE_system_breadcrumb_alter (Breadcrumb & $breadcrumb, RouteMatchInterface $route_match, อาร์เรย์ $context) {
  // ต่อท้ายชื่อเพจปัจจุบันใน breadcrumb สำหรับเส้นทางที่ไม่ใช่ผู้ดูแลระบบ
  ถ้า ($breadcrumb && !\Drupal::service('router.admin_context')->isAdminRoute()) {
    $links = $breadcrumb->getLinks();
    foreach (ลิงก์ $ เป็น $ ลิงก์) {
      $parameters = $link->getUrl()->getRouteParameters();
      ถ้า ($ พารามิเตอร์) {
        // ตรวจสอบให้แน่ใจว่า breadcrumb ได้รับการอัปเดตเมื่อชื่อโหนดเปลี่ยนแปลง
        $breadcrumb->addCacheTags(['node:' . $parameters['node']]);
        $breadcrumb->addCacheContexts(['url']);
      }
    }
  }
}

บันทึก: เกล็ดขนมปังง่าย ติดตั้งโมดูลแล้ว

Kevin avatar
in flag
พวกเขาเชื่อมโยงกันจริง ๆ ในเมนูหรือไม่? พวกเขาเชื่อมต่อกันอย่างไร? นามแฝงไม่ได้บ่งบอกถึงการพึ่งพาแคช
4uk4 avatar
cn flag
โดยปกติคุณจะไม่แก้ปัญหาการแคชใน hook_node_update() ปลั๊กอิน GraphQL ที่สร้างเบรดครัมบ์ต้องเพิ่มแท็กแคช จากนั้นแท็กเหล่านั้นจะไม่ถูกต้องโดยอัตโนมัติเมื่อมีการบันทึกโหนด
berramou avatar
gb flag
ฉันได้พยายามเพิ่มโหนด cachetag ให้กับ breadcrumbs ตามที่ฉันได้กล่าวถึงในการแก้ไขของฉัน แต่ก็ไม่ได้ผล บางทีฉันควรเพิ่ม cacheTag อื่น ฉันขาดอะไรไป
berramou avatar
gb flag
@Kevin ไม่ พวกเขาไม่ได้เชื่อมโยงในเมนู breadcrumbs ที่สร้างขึ้นโดยอัตโนมัติโดยใช้โมดูล Easy Breadcrumb
4uk4 avatar
cn flag
ตกลง หากเบรดครัมบ์มีแท็กแคชที่จำเป็นทั้งหมด ก็ยังไม่ชัดเจนว่าโค้ดใดกำลังสร้างผลลัพธ์ GraphQL ไม่พบปลั๊กอินดังกล่าวในโมดูลหลัก คุณมีโมดูลเพิ่มเติมสำหรับสิ่งนั้นหรือไม่?
berramou avatar
gb flag
ไม่มีโมดูลเพิ่มเติมสำหรับ breadcrumbs ฉันใช้โมดูล qraphQl officiel รุ่น 3.X ฉันพบฟิลด์ Breadcrumb ที่กำหนดไว้ที่นี่ **graphql/modules/graphql_core/src/Plugin/GraphQL/Fields/Breadcrumbs/Breadcrumbs.php**
4uk4 avatar
cn flag
นี่คือเวอร์ชันก่อนหน้า[อัปเดตล่าสุด](https://git.drupalcode.org/project/graphql/-/commit/58a9b7464bc6cf4aa78632a0efee83f911c8522e) สำหรับออบเจ็กต์โค้ดนี้กำลังแก้ไขปัญหานี้อย่างแน่นอน แต่ฉันไม่รู้ว่าการอัปเดตนี้สำเร็จหรือไม่ คุณสามารถแจ้งปัญหาได้หากคุณสามารถสร้างแท็กแคชที่ขาดหายไปได้อีกครั้ง และเวอร์ชันนี้ยังคงอยู่
berramou avatar
gb flag
ใช่ ฉันมีการอัปเดตนี้ มันเป็นรุ่น 3.X ล่าสุดที่ติดตั้งแล้ว!
4uk4 avatar
cn flag
คุณสามารถยืนยันการอัปเดตสำเร็จหรือไม่ ตัวอย่างเช่น โดยการตรวจสอบว่าแท็กแคชที่คุณเพิ่มไปยังเบรดครัมบ์จบลงด้วยการตอบกลับที่แคช
Score:0
ธง cn

ฉันไม่ทราบการใช้งานแคชของปลั๊กอินฟิลด์ GraphQL 3.x แต่เท่าที่ฉันสามารถบอกรหัสนี้ได้ (แม้หลังจาก ปรับปรุงล่าสุด จากปี 2018) ไม่รวบรวมข้อมูลเมตาของเบรดครัมบ์เนื่องจากได้รับเฉพาะลิงก์:

ฟังก์ชันที่ได้รับการป้องกัน SolveValues($value, array $args, ResolveContext $context, ResolveInfo $info) {
    ถ้า ($ มูลค่าอินสแตนซ์ของ URL) {
      $resolve = $this->subRequestBuffer->add($value, function () {
        $links = $this->breadcrumbManager->build($this->routeMatch)->getLinks();
        คืน $links;
      });

      ส่งคืนฟังก์ชัน ($value, อาร์เรย์ $args, ResolveContext $context, ResolveInfo $info) ใช้ ($resolve) {
        /** @var \Drupal\graphql\GraphQL\Cache\CacheableValue $response */
        $response = $resolve();
        $links = $response->getValue();

        foreach (ลิงก์ $ เป็น $ ลิงก์) {
          สร้าง CacheableValue ใหม่ ($link, [$response]);
        }
      };
    }
  }

มันไม่ควรได้รับวัตถุเบรดครัมบ์เพื่อเพิ่มข้อมูลเมตาที่แคชได้ใช่หรือไม่

ฟังก์ชันที่ได้รับการป้องกัน SolveValues($value, array $args, ResolveContext $context, ResolveInfo $info) {
    ถ้า ($ มูลค่าอินสแตนซ์ของ URL) {
      $resolve = $this->subRequestBuffer->add($value, function () {
        $breadcrumb = $this->breadcrumbManager->build($this->routeMatch);
        คืนค่า $breadcrumb;
      });

      ส่งคืนฟังก์ชัน ($value, อาร์เรย์ $args, ResolveContext $context, ResolveInfo $info) ใช้ ($resolve) {
        /** @var \Drupal\graphql\GraphQL\Cache\CacheableValue $response */
        $response = $resolve();
        $breadcrumb = $response->getValue();
        $links = $breadcrumb->getLinks();

        foreach (ลิงก์ $ เป็น $ ลิงก์) {
          สร้าง CacheableValue ใหม่ ($link, [$response, $breadcrumb]);
        }
      };
    }
  }

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา