У меня есть несколько вопросов о Sapper/Svelte

Я только начал использовать Sapper ( https://sapper.svelte.technology/) в первый раз. Мне очень нравится это до сих пор. Одна из вещей, которые мне нужно сделать, это показать список компонентов, доступных в моем приложении, и показать информацию о них. В идеале есть способ изменить внешний вид компонента на основе динамических привязок на странице.

У меня есть несколько вопросов об использовании фреймворка.

Сначала я предоставлю фрагмент своего кода, а затем снимок экрана:

[slug].html
-----------

<:Head>
<title>{{info.title}}</title>
</:Head>

<Layout page="{{slug}}">
    <h1>{{info.title}}</h1>

    <div class="content">
         <TopBar :organization_name />
    <br>
    <h3>Attributes</h3>
    {{#each Object.keys(info.attributes) as attribute}}
    <p>{{info.attributes[attribute].description}} <input type="text" on:keyup="updateComponent(this.value)" value="Org Name" /></p>
    {{/each}}
    </div>
</Layout>

<script>
import Layout from '../_components/components/Layout.html';
import TopBar from '../../_components/header/TopBar.html';

let COMPONENTS = require('../_config/components.json');

export default {
    components: {
        Layout, TopBar
    },

      methods: {
          updateComponent(value) {
            this.set({organization_name: value});
          }
      },

  data() {
      return {
        organization_name: 'Org Name'
      }
  },

  preload({ params, query }) {

    params['info'] = COMPONENTS.components[params.slug];

    return params;
  }

};
</script>

Теперь мои вопросы:

  1. Я замечаю, что не могу #each через мой объект. Я должен пройтись по его ключам. Было бы хорошо, если бы я мог сделать что-то вроде этого:

    {{#each info.attributes как атрибут}}

    {{attribute.description}}

    {{/}} Каждая

  2. До Sapper я использовал модуль Angular-translate, который мог выполнять переводы строк на основе заданного файла JSON. Кто-нибудь знает, существует ли эквивалент Sapper/Svelte, или это то, что мне, возможно, нужно придумать самостоятельно?

  3. Я не привык делать импорт. Я больше пользуюсь внедрением зависимостей в Angular, который выглядит чище (без путей). Есть ли способ, которым я могу создать COMPONENTS константа, которая может использоваться во всех моих файлах, или мне нужно будет импортировать файл JSON при каждом доступе к его данным?

  4. В качестве продолжения #3, мне интересно, есть ли способ лучше включить файлы вместо того, чтобы полагаться на использование ../.. перемещаться по структуре папок? Если бы я изменил путь к одному из моих файлов, мой Терминал будет жаловаться и выдавать ошибки, что приятно, но, тем не менее, мне интересно, есть ли лучший способ импортировать мои файлы.

  5. Я знаю, что должен быть лучший способ реализовать то, что я реализовал в своем примере. По сути, вы видите поле ввода рядом с атрибутом, и если я внесу туда изменения, я вызываю updateComponent функция, которая затем делает this.set() в текущей области, чтобы переопределить привязку. Это работает, но мне было интересно, есть ли способ избежать этой функции. Я подумал, что это возможно, что вы можете связать значение ввода и автоматически обновить мой <TopBar> привязка компонентов... может быть?

  6. preload метод дает мне доступ к params, Что я хочу знать, если есть какой-то способ для меня, чтобы получить доступ к params.slug без функции предварительной нагрузки.

Было бы здорово, если бы какой-то эксперт переписал то, что я сделал, как можно лучше, возможно, ответив на некоторые мои вопросы.

1 ответ

Решение
  1. Svelte будет выполнять итерации только по объектам, похожим на массивы, потому что невозможно гарантировать согласованное поведение с объектами - он отбрасывает различные граничные случаи, которые лучше всего решать на уровне приложения. Вы можете делать такие вещи, просто используя стандартные идиомы JavaScript:
{{#each Object.values(info.attributes) as attr}}
  <p>{{attr.description}} ...</p>
{{/each}}

<!-- or, if you need the key as well -->
{{#each Object.entries(info.attributes) as [key, value]}}
  <p>{{attr.description}} ...</p>
{{/each}}
  1. Не знаю о прямом угловом переводе, но простое решение i18n - получить JSON в preload:
preload({ params, query }) {
  return fetch(`/i18n/${locale}.json`)
    .then(r => r.json())
    .then(dict => {
      return { dict };
    });
}

Затем вы можете ссылаться на такие вещи, как {{dict["hello"]}} в вашем шаблоне. Более сложное решение будет загружать только строки, необходимые для текущей страницы, и кэшировать все и т. Д., Но основная идея та же.

  1. Я думаю, вы могли бы сделать это:
// app/client.js (assuming Sapper >= 0.7)
import COMPONENTS from './config/components.json';
window.COMPONENTS = COMPONENTS;

// app/server.js
import COMPONENTS from './config/components.json';
global.COMPONENTS = COMPONENTS;

Импорт не так уж и плох! Хорошо, чтобы зависимости модуля были явными.

  1. Вы можете использовать resolve.modules в конфигах вашего веб-пакета: https://webpack.js.org/configuration/resolve/

  2. Это было бы хорошим местом для использования двусторонней привязки:

{{#each Object.values(info.attributes) as attr}}
  <p>{{attr.description}} <input bind:value=organization_name /></p>
{{/each}}
  1. Да, params объект всегда доступен на ваших страницах (не вложенные компоненты, если вы не пропустите опору, но все ваши компоненты верхнего уровня, такие как routes/whatever/[slug].html) - так что вы можете ссылаться на него в шаблонах как {{params.slug}}или внутри хуков и методов жизненного цикла, как this.get('params').slug, использует ли данный компонент preload,
Другие вопросы по тегам