Puncte:1

Cum pot extinde Serializatorul pentru a gestiona un tip de câmp personalizat?

drapel cn

Încerc să prelungesc Serializare pentru a obține Câmp JSON modul pentru a returna un obiect JSON în loc de JSON stringificat.

Scop: Când accesez o entitate care conține un câmp JSON folosind JSON:API, vreau un obiect JSON pentru valoarea câmpului (în prezent, JSON-ul stringificat este returnat).

Cred că ceea ce trebuie să fac este să extind unul dintre normalizatorii de bază și să îl folosesc pentru a adăuga un json_decode() Etapa.

Este ceva documentație despre modul în care Serializer gestionează entitățile dar este învechit (ultima actualizare în 2017 înainte ca JSON:API să facă parte din nucleu, iar codul actual nu seamănă deloc cu ceea ce este afișat.)

Am încercat să extind FieldNormalizer în /json_field/src/Normalizer/JsonFieldNormalizer.php.
Cu toate acestea, nu sunt sigur că aceasta este abordarea corectă, deoarece există și un FieldItemNormalizer și TypedDataNormalizer. Pentru a schimba modul în care un câmp este scos în JSON:API, ce clasă ar trebui să extind?

<?php

spațiu de nume Drupal\json_field\Normalizer;

utilizați Drupal\Core\Field\FieldDefinitionInterface;
utilizați Drupal\json_field\Plugin\Field\FieldType\NativeJSONItem;
utilizați Drupal\jsonapi\JsonApiResource\ResourceObject;
utilizați Drupal\jsonapi\Normalizer\FieldNormalizer;
utilizați Drupal\jsonapi\Normalizer\Value\CacheableNormalization;
utilizați Drupal\jsonapi\ResourceType\ResourceType;

clasa JsonFieldNormalizer extinde FieldNormalizer {

  /**
   * {@inheritdoc}
   */
  protejat $supportedInterfaceOrClass = NativeJSONItem::class;

  /**
   * {@inheritdoc}
   */
  funcția publică normalize($câmp, $format = NULL, matrice $context = []) {
    $field_name = $field->getName();
    \Drupal::logger('json_field')->info("Câmpul are numele $field_name");
    assert($field instance of NativeJSONItem);
    /** @var \Drupal\Core\Field\FieldItemListInterface $field */ $normalized_items = $this->normalizeFieldItems($field, $format, $context);
    assert($context['resource_object'] instanceof ResourceObject);
    returnează $context['resource_object']->getResourceType()->getFieldByInternalName($field->getName())->hasOne()
      ? array_shift($normalized_items) ?: CacheableNormalization::permanent(NULL)
      : CacheableNormalization::aggregate($articole_normalizate);
  }

Și am adăugat clasa la json_field.services.yml:

Servicii:
  json_field.views:
    clasa: Drupal\json_field\JSONViews
  json_field.normalizer.field.json_field:
    clasa: Drupal\json_field\Normalizer\JsonFieldNormalizer
    Etichete:
      - { nume: normalizator, prioritate: 1 }

Cu toate acestea, după reconstruirea memoriei cache și accesarea unor câmpuri JSON prin JSON:API, nu văd nimic în jurnale, așa că se pare că clasa nu este preluată.

4uk4 avatar
drapel cn
Sunt câteva lucruri care sunt inconsistente. Extindeți FieldNormalizer, dar $supportedInterfaceOrClass este cel al unui element de câmp. Deci mai bine extindeți FieldItemNormalizer. Implementați un serializator jsonapi, dar eticheta de serviciu nu este `{ name: jsonapi_normalizer, priority: 1 }`.
drapel cn
@4uk4 Mulțumesc, am încercat inițial să-l adaug ca `jsonapi_normalizer`, dar când am făcut asta, am primit eroarea `LogicException: JSON:API nu permite adăugarea mai multor normalizatori!` Tocmai am încercat să extind FieldItemNormalizer și primesc aceeași problemă (nicio înregistrare nu este declanșată când accesez câmpul prin JSON:API).
4uk4 avatar
drapel cn
OK, tocmai am încercat să subliniez neconcordanțe. Când spun @intern, chiar vorbesc serios. Citind comentariile din [această ediție](https://www.drupal.org/project/drupal/issues/2923779) probabil că trebuie să adăugați la câmpul dvs. personalizat, de asemenea, date tastate personalizate (puteți extinde pur și simplu DataDefinition ați definit acum proprietățile câmpului) și apoi definiți un normalizator pentru aceasta.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.