У меня есть несколько вопросов о 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>
Теперь мои вопросы:
Я замечаю, что не могу
#each
через мой объект. Я должен пройтись по его ключам. Было бы хорошо, если бы я мог сделать что-то вроде этого:{{#each info.attributes как атрибут}}
{{attribute.description}}
{{/}} Каждая
До Sapper я использовал модуль Angular-translate, который мог выполнять переводы строк на основе заданного файла JSON. Кто-нибудь знает, существует ли эквивалент Sapper/Svelte, или это то, что мне, возможно, нужно придумать самостоятельно?
Я не привык делать импорт. Я больше пользуюсь внедрением зависимостей в Angular, который выглядит чище (без путей). Есть ли способ, которым я могу создать
COMPONENTS
константа, которая может использоваться во всех моих файлах, или мне нужно будет импортировать файл JSON при каждом доступе к его данным?В качестве продолжения #3, мне интересно, есть ли способ лучше включить файлы вместо того, чтобы полагаться на использование
../..
перемещаться по структуре папок? Если бы я изменил путь к одному из моих файлов, мой Терминал будет жаловаться и выдавать ошибки, что приятно, но, тем не менее, мне интересно, есть ли лучший способ импортировать мои файлы.Я знаю, что должен быть лучший способ реализовать то, что я реализовал в своем примере. По сути, вы видите поле ввода рядом с атрибутом, и если я внесу туда изменения, я вызываю
updateComponent
функция, которая затем делаетthis.set()
в текущей области, чтобы переопределить привязку. Это работает, но мне было интересно, есть ли способ избежать этой функции. Я подумал, что это возможно, что вы можете связать значение ввода и автоматически обновить мой<TopBar>
привязка компонентов... может быть?preload
метод дает мне доступ кparams
, Что я хочу знать, если есть какой-то способ для меня, чтобы получить доступ кparams.slug
без функции предварительной нагрузки.
Было бы здорово, если бы какой-то эксперт переписал то, что я сделал, как можно лучше, возможно, ответив на некоторые мои вопросы.
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}}
- Не знаю о прямом угловом переводе, но простое решение i18n - получить JSON в
preload
:
preload({ params, query }) {
return fetch(`/i18n/${locale}.json`)
.then(r => r.json())
.then(dict => {
return { dict };
});
}
Затем вы можете ссылаться на такие вещи, как {{dict["hello"]}}
в вашем шаблоне. Более сложное решение будет загружать только строки, необходимые для текущей страницы, и кэшировать все и т. Д., Но основная идея та же.
- Я думаю, вы могли бы сделать это:
// 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;
Импорт не так уж и плох! Хорошо, чтобы зависимости модуля были явными.
Вы можете использовать
resolve.modules
в конфигах вашего веб-пакета: https://webpack.js.org/configuration/resolve/Это было бы хорошим местом для использования двусторонней привязки:
{{#each Object.values(info.attributes) as attr}}
<p>{{attr.description}} <input bind:value=organization_name /></p>
{{/each}}
- Да,
params
объект всегда доступен на ваших страницах (не вложенные компоненты, если вы не пропустите опору, но все ваши компоненты верхнего уровня, такие какroutes/whatever/[slug].html
) - так что вы можете ссылаться на него в шаблонах как{{params.slug}}
или внутри хуков и методов жизненного цикла, какthis.get('params').slug
, использует ли данный компонентpreload
,