Score:1

ฉันจะขยาย Serializer เพื่อจัดการประเภทฟิลด์ที่กำหนดเองได้อย่างไร

ธง cn

ฉันพยายามที่จะขยาย การทำให้เป็นอนุกรม เพื่อรับ ฟิลด์ JSON โมดูลเพื่อส่งคืนวัตถุ JSON แทน JSON ที่สตริง

เป้าหมาย: เมื่อฉันเข้าถึงเอนทิตีที่มีฟิลด์ JSON โดยใช้ JSON:API ฉันต้องการวัตถุ JSON สำหรับค่าฟิลด์ (ปัจจุบัน JSON แบบสตริงจะถูกส่งคืน)

ฉันคิดว่าสิ่งที่ฉันต้องทำคือขยายหนึ่งใน core normalizers และใช้เพื่อเพิ่ม a json_decode() ขั้นตอน

มีบางอย่าง เอกสารเกี่ยวกับวิธีที่ Serializer จัดการกับเอนทิตี แต่ล้าสมัย (อัปเดตครั้งล่าสุดในปี 2560 ก่อนที่ JSON:API จะเป็นส่วนหนึ่งของคอร์ และโค้ดปัจจุบันไม่เหมือนกับที่แสดง)

ฉันพยายามขยาย FieldNormalizer ใน /json_field/src/Normalizer/JsonFieldNormalizer.php.
อย่างไรก็ตาม ฉันไม่มั่นใจว่านี่เป็นแนวทางที่ถูกต้อง เนื่องจากมี FieldItemNormalizer และ TypedDataNormalizer อยู่ด้วย หากต้องการเปลี่ยนวิธีเอาต์พุตฟิลด์ใน JSON:API ฉันควรขยายคลาสใด

<?php

เนมสเปซ Drupal\json_field\Normalizer;

ใช้ Drupal\Core\Field\FieldDefinitionInterface;
ใช้ Drupal\json_field\Plugin\Field\FieldType\NativeJSONItem
ใช้ Drupal\jsonapi\JsonApiResource\ResourceObject
ใช้ Drupal\jsonapi\Normalizer\FieldNormalizer
ใช้ Drupal\jsonapi\Normalizer\Value\CacheableNormalization;
ใช้ Drupal\jsonapi\ResourceType\ResourceType;

คลาส JsonFieldNormalizer ขยาย FieldNormalizer {

  /**
   * {@inheritdoc}
   */
  ป้องกัน $supportedInterfaceOrClass = NativeJSONItem::class;

  /**
   * {@inheritdoc}
   */
  ฟังก์ชั่นสาธารณะ normalize($field, $format = NULL, array $context = []) {
    $field_name = $field->getName();
    \Drupal::logger('json_field')->info("ฟิลด์มีชื่อ $field_name");
    ยืนยัน ($ ฟิลด์อินสแตนซ์ของ NativeJSONItem);
    /** @var \Drupal\Core\Field\FieldItemListInterface $field */ $normalized_items = $this->normalizeFieldItems($field, $format, $context);
    ยืนยัน ($ บริบท ['resource_object'] อินสแตนซ์ของ ResourceObject);
    ส่งคืน $context['resource_object']->getResourceType()->getFieldByInternalName($field->getName())->hasOne()
      ? array_shift($normalized_items) ?: CacheableNormalization::permanent(NULL)
      : CacheableNormalization::aggregate($normalized_items);
  }

และฉันได้เพิ่มชั้นเรียนไปที่ json_field.services.yml:

บริการ:
  json_field.views:
    คลาส: Drupal\json_field\JSONViews
  json_field.normalizer.field.json_field:
    คลาส: Drupal\json_field\Normalizer\JsonFieldNormalizer
    แท็ก:
      - { ชื่อ: normalizer, ลำดับความสำคัญ: 1 }

อย่างไรก็ตาม หลังจากสร้างแคชใหม่และเข้าถึงฟิลด์ JSON บางส่วนผ่าน JSON:API แล้ว ฉันไม่เห็นสิ่งใดในบันทึก ดังนั้นดูเหมือนว่าจะไม่มีการรับคลาส

4uk4 avatar
cn flag
มีบางอย่างที่ไม่สอดคล้องกัน คุณกำลังขยาย FieldNormalizer แต่ $supportedInterfaceOrClass เป็นของรายการฟิลด์ ดังนั้นควรขยาย FieldItemNormalizer ให้ดียิ่งขึ้น คุณกำลังใช้ jsonapi serializer แต่แท็กบริการไม่ใช่ `{ ชื่อ: jsonapi_normalizer, ลำดับความสำคัญ: 1 }`
cn flag
@4uk4 ขอบคุณ เดิมทีฉันพยายามเพิ่มเป็น `jsonapi_normalizer` แต่เมื่อฉันทำอย่างนั้น ฉันได้รับข้อผิดพลาด `LogicException: JSON:API ไม่อนุญาตการเพิ่ม normalizers!` ฉันเพิ่งลองขยาย FieldItemNormalizer และฉันได้รับ ปัญหาเดียวกัน (ไม่มีการเรียกใช้การบันทึกเมื่อฉันเข้าถึงฟิลด์ผ่าน JSON:API)
4uk4 avatar
cn flag
ตกลง ฉันเพิ่งพยายามชี้ให้เห็นความไม่สอดคล้องกัน เมื่อพวกเขาพูดว่า @internal พวกเขาหมายความตามนั้นจริงๆ การอ่านความคิดเห็นใน [ปัญหานี้] (https://www.drupal.org/project/drupal/issues/2923779) คุณอาจต้องเพิ่มข้อมูลที่พิมพ์แบบกำหนดเองลงในช่องที่คุณกำหนดเองด้วย (คุณสามารถขยาย DataDefinition ตอนนี้คุณได้กำหนดไว้ในคุณสมบัติของฟิลด์) จากนั้นกำหนด normalizer สำหรับสิ่งนี้

โพสต์คำตอบ

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