我刚刚开始第一次使用 Sapper ( https://sapper.svelte.technology )。到目前为止我真的很喜欢它。我需要它做的一件事是显示我的应用程序中可用组件的列表并显示有关它们的信息。理想情况下,有一种方法可以根据页面上的动态绑定(bind)更改组件的外观。
我有几个关于使用该框架的问题。
首先,我将提供我的代码片段,然后是屏幕截图:
[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}}
{{/each}}
在使用 Sapper 之前,我会使用 Angular-translate 模块,它可以根据给定的 JSON 文件对字符串进行翻译。有谁知道是否存在 Sapper/Svelte 等价物,或者这是否是我可能需要自己想出的东西?
我不习惯做进口。我更习惯在 Angular 中使用依赖注入(inject),它看起来更简洁(没有路径)。有什么方法可以创建
COMPONENTS
可以在我的整个文件中使用的常量,还是我需要在每次需要访问其数据时导入 JSON 文件?作为 #3 的后续,我想知道是否有更好的方法来包含文件,而不必依赖于使用
../..
浏览我的文件夹结构?如果我要更改其中一个文件的路径,我的终端会提示并给出错误,这很好,但我仍然想知道是否有更好的方法来导入我的文件。我知道必须有更好的方法来实现我在示例中实现的内容。基本上,您会在属性旁边看到一个输入框,如果我在那里进行更改,我会调用
updateComponent
然后执行this.set()
的函数在当前范围内覆盖绑定(bind)。这行得通,但我想知道是否有某种方法可以避免该功能。我认为您可以绑定(bind)输入的值并让它自动更新我的<TopBar>
组件绑定(bind)……也许?preload
方法让我可以访问params
.我想知道我是否有办法访问params.slug
没有预加载功能。
真正酷的是让一些专家以尽可能最好的方式重写我所做的,可能会解决我的一些问题。
最佳答案
- 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}}
- 不知道直接的 Angular 翻译等效项,但一个简单的 i18n 解决方案是在
preload
中获取一些 JSON:
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;
虽然导入并没有那么糟糕!明确模块的依赖关系是有好处的。
您可以在您的 webpack 配置中使用
resolve.modules
字段:https://webpack.js.org/configuration/resolve/#resolve-modules这是使用双向绑定(bind)的好地方:
{{#each Object.values(info.attributes) as attr}}
<p>{{attr.description}} <input bind:value=organization_name /></p>
{{/each}}
- 是的,
params
对象在您的页面中始终可用(不是嵌套组件,除非您向下传递 prop,但所有顶级组件,如routes/whatever/[slug .html
) — 这样您就可以在模板中将其引用为{{params.slug}}
,或者在生命周期钩子(Hook)和方法中将其引用为this.get('params') .slug
,给定组件是否使用preload
。
关于javascript - 我对 Sapper/Svelte 有一些疑问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49077362/