Concepts
Sérialisation
9 min
le modèle de données de slate a été construit en tenant compte de la sérialisation plus précisément, ses nœuds de texte sont définis de manière à les rendre plus faciles à lire d'un coup d'œil, mais aussi faciles à sérialiser dans des formats courants comme html et markdown et, parce que slate utilise du json brut pour ses données, vous pouvez écrire la logique de sérialisation très facilement texte brut par exemple, prendre la valeur d'un éditeur et retourner du texte brut import { node } from 'slate' const serialize = nodes => { return nodes map(n => node string(n)) join('\n') } ici, nous prenons les nœuds enfants d'un éditeur comme un nœuds argument, et retournons une représentation en texte brut où chaque nœud de premier niveau est séparé par un seul \n caractère de nouvelle ligne pour une entrée de const nodes = \[ { type 'paragraph', children \[{ text 'an opening paragraph ' }], }, { type 'quote', children \[{ text 'a wise quote ' }], }, { type 'paragraph', children \[{ text 'a closing paragraph!' }], }, ] vous obtiendriez an opening paragraph a wise quote a closing paragraph! remarquez comment le bloc de citation n'est pas distinguable de quelque manière que ce soit, c'est parce que nous parlons de texte brut mais vous pouvez sérialiser les données en tout ce que vous voulez—c'est juste du json après tout html par exemple, voici une fonction de sérialisation pour html import escapehtml from 'escape html' import { text } from 'slate' const serialize = node => { if (text istext(node)) { let string = escapehtml(node text) if (node bold) { string = `\<strong>${string}\</strong>` } return string } const children = node children map(n => serialize(n)) join('') switch (node type) { case 'quote' return `\<blockquote>\<p>${children}\</p>\</blockquote>` case 'paragraph' return `\<p>${children}\</p>` case 'link' return `\<a href="${escapehtml(node url)}">${children}\</a>` default return children } } celle ci est un peu plus consciente que le sérialiseur de texte brut ci dessus elle est en fait récursive afin qu'elle puisse continuer à itérer plus profondément à travers les enfants d'un nœud jusqu'à ce qu'elle atteigne les nœuds de texte feuilles et pour chaque nœud qu'elle reçoit, elle le convertit en une chaîne html elle prend également un seul nœud en entrée au lieu d'un tableau, donc si vous passiez un éditeur comme const editor = { children \[ { type 'paragraph', children \[ { text 'an opening paragraph with a ' }, { type 'link', url 'https //example com', children \[{ text 'link' }], }, { text ' in it ' }, ], }, { type 'quote', children \[{ text 'a wise quote ' }], }, { type 'paragraph', children \[{ text 'a closing paragraph!' }], }, ], // `editor` objects also have other properties that are omitted here } vous recevrez en retour (sauts de ligne ajoutés pour la lisibilité) \<p>an opening paragraph with a \<a href="https //example com">link\</a> in it \</p> \<blockquote>\<p>a wise quote \</p>\</blockquote> \<p>a closing paragraph!\</p> c'est vraiment aussi simple que ça ! désérialisation un autre cas d'utilisation courant dans slate est de faire l'inverse—la désérialisation c'est lorsque vous avez une entrée arbitraire et que vous souhaitez la convertir en une structure json compatible avec slate par exemple, lorsque quelqu'un colle du html dans votre éditeur et que vous souhaitez vous assurer qu'il soit analysé avec le formatage approprié pour votre éditeur slate a un helper intégré pour cela le slate hyperscript package la façon la plus courante d'utiliser slate hyperscript est d'écrire des documents jsx, par exemple lors de l'écriture de tests vous pourriez l'utiliser comme ceci / @jsx jsx / import { jsx } from 'slate hyperscript' const input = ( \<fragment> \<element type="paragraph">a line of text \</element> \</fragment> ) et la fonctionnalité jsx de votre compilateur (babel, typescript, etc ) transformerait cette entrée variable en const input = \[ { type 'paragraph', children \[{ text 'a line of text ' }], }, ] c'est génial pour les cas de test, ou les endroits où vous souhaitez pouvoir écrire beaucoup d'objets slate dans une forme très lisible cependant ! cela n'aide pas avec la désérialisation mais slate hyperscript n'est pas seulement pour jsx c'est juste un moyen de construire des arbres de contenu slate ce qui se trouve être exactement ce que vous voulez faire lorsque vous désérialisez quelque chose comme du html par exemple, voici une fonction de désérialisation pour html import { jsx } from 'slate hyperscript' const deserialize = el => { if (el nodetype === 3) { return el textcontent } else if (el nodetype !== 1) { return null } let children = array from(el childnodes) map(deserialize) if (children length === 0) { children = \[{ text '' }] } switch (el nodename) { case 'body' return jsx('fragment', {}, children) case 'br' return '\n' case 'blockquote' return jsx('element', { type 'quote' }, children) case 'p' return jsx('element', { type 'paragraph' }, children) case 'a' return jsx( 'element', { type 'link', url el getattribute('href') }, children ) default return el textcontent } } il prend un el objet d'élément html et renvoie un fragment slate donc, si vous avez une chaîne html, vous pouvez la parser et la désérialiser comme ceci const html = ' ' const document = new domparser() parsefromstring(html, 'text/html') deserialize(document body) avec cette entrée \<p>an opening paragraph with a \<a href="https //example com">link\</a> in it \</p> \<blockquote>\<p>a wise quote \</p>\</blockquote> \<p>a closing paragraph!\</p> vous obtiendrez ce résultat const fragment = \[ { type 'paragraph', children \[ { text 'an opening paragraph with a ' }, { type 'link', url 'https //example com', children \[{ text 'link' }], }, { text ' in it ' }, ], }, { type 'quote', children \[ { type 'paragraph', children \[{ text 'a wise quote ' }], }, ], }, { type 'paragraph', children \[{ text 'a closing paragraph!' }], }, ] et tout comme la fonction de sérialisation, vous pouvez l'étendre pour répondre aux besoins exacts de votre modèle de domaine
