简体   繁体   English

我对Sapper / Svelte有疑问

[英]I have some questions about Sapper/Svelte

I just started using Sapper ( https://sapper.svelte.technology ) for the first time. 我刚开始第一次使用Sapper( https://sapper.svelte.technology )。 I really like it so far. 到目前为止,我真的很喜欢。 One of the things I need it to do is show a list of the components available in my application and show information about them. 我需要做的一件事是显示应用程序中可用组件的列表,并显示有关它们的信息。 Ideally have a way to change the way the component looks based on dynamic bindings on the page. 理想情况下,有一种方法可以根据页面上的动态绑定来更改组件的外观。

I have a few questions about using the framework. 我对使用框架有一些疑问。

First, I'll provide a snippet of my code, and then a screenshot: 首先,我将提供一段代码,然后是一个屏幕截图:

[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>

在此处输入图片说明

Now my questions: 现在我的问题是:

  1. I notice I can't #each through my object. 我发现我不能#each通过我的对象。 I have to loop through its keys. 我必须循环浏览其键。 Would be nice if I could do something like this: 如果我可以做这样的事情会很好:

    {{#each info.attributes as attribute }} {{#每个info.attributes作为属性}}

    {{attribute.description}}

    {{/each}} {{/每}}

  2. Before Sapper, I would use Angular-translate module that could do translations on strings based on a given JSON file. 在Sapper之前,我将使用Angular-translate模块,该模块可以基于给定的JSON文件对字符串进行翻译。 Does anyone know if a Sapper/Svelte equivalent exists, or is that something I might need to come up with on my own? 有谁知道Sapper / Svelte等效产品是否存在,或者我可能需要自己提出一些建议?

  3. I'm not used to doing imports. 我不习惯进口。 I'm more use to dependency injection in Angular which looks a bit cleaner (no paths). 我更多地使用Angular中的依赖项注入,它看起来更干净(没有路径)。 Is there some way I can create a COMPONENTS constant that could be used throughout my files, or will I need to import a JSON file in every occurence that I need access to its data? 有什么方法可以创建可在我的整个文件中使用的COMPONENTS常量,还是在每次需要访问其数据的事件中都需要导入JSON文件?

  4. As a follow-up to #3, I wonder if there is a way to better include files instead of having to rely on using ../.. to navigate through my folder structure? 作为#3的后续工作,我想知道是否有办法更好地包含文件,而不必依靠使用../..来浏览我的文件夹结构? If I were to change the path of one of my files, my Terminal will complain and give errors which is nice, but still, I wonder if there is a better way to import my files. 如果要更改其中一个文件的路径,终端会抱怨并给出错误,这很不错,但是我仍然想知道是否有更好的导入文件的方法。

  5. I know there has got to be a better way to implement what I implemented in my example. 我知道必须有一种更好的方法来实现我在示例中实现的功能。 Basically, you see an input box beside an attribute, and if I make changes there, I am calling an updateComponent function which then does a this.set() in the current scope to override the binding. 基本上,您会在属性旁边看到一个输入框,如果我在其中进行了更改,我将调用updateComponent函数,该函数然后在当前作用域中执行this.set()来覆盖绑定。 This works, but I was wondering if there was some way to avoid the function. 这可行,但是我想知道是否有某种方法可以避免该功能。 I figured it's possible that you can bind the value of the input and have it automatically update my <TopBar> component binding... maybe? 我认为您可以绑定输入的值,并让它自动更新我的<TopBar>组件绑定...也许?

  6. The preload method gives me access to params . preload方法使我可以访问params What I want to know if there is some way for me to get access to params.slug without the preload function. 我想知道是否可以通过某种方式在没有预加载功能的情况下访问params.slug

What would be really cool is to have some expert rewrite what I've done in the best possible way, possibly addressing some of my questions. 真的很酷,就是请一些专家以最好的方式重写我所做的事情,可能会解决我的一些问题。

  1. Svelte will only iterate over array-like objects, because it's not possible to guarantee consistent behaviour with objects — it throws up various edge cases that are best solved at an app level. Svelte将仅迭代类似数组的对象,因为不可能保证对象的行为一致-它抛出了各种边缘情况,这些情况最好在应用程序级别解决。 You can do this sort of thing, just using standard JavaScript idioms: 您可以使用标准的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. Not aware of a direct angular-translate equivalent, but a straightforward i18n solution is to fetch some JSON in preload : 没有意识到直接的角度转换等效项,但是一个简单的i18n解决方案是在preload获取一些JSON:
preload({ params, query }) {
  return fetch(`/i18n/${locale}.json`)
    .then(r => r.json())
    .then(dict => {
      return { dict };
    });
}

Then, you can reference things like {{dict["hello"]}} in your template. 然后,您可以在模板中引用诸如{{dict["hello"]}}的内容。 A more sophisticated solution would only load the strings necessary for the current page, and would cache everything etc, but the basic idea is the same. 一个更复杂的解决方案将仅加载当前页面所需的字符串,并缓存所有内容等,但是基本思想是相同的。

  1. I guess you could do this: 我想你可以这样做:
// 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;

Importing isn't that bad though! 导入还算不错! It's good for a module's dependencies to be explicit. 明确模块的依赖关系是有好处的。

  1. You can use the resolve.modules field in your webpack configs: https://webpack.js.org/configuration/resolve/#resolve-modules 您可以使用resolve.modules在你的WebPack CONFIGS领域: https://webpack.js.org/configuration/resolve/#resolve-modules

  2. This would be a good place to use two-way binding: 这将是使用双向绑定的好地方:

{{#each Object.values(info.attributes) as attr}}
  <p>{{attr.description}} <input bind:value=organization_name /></p>
{{/each}}
  1. Yep, the params object is always available in your pages (not nested components, unless you pass the prop down, but all your top-level components like routes/whatever/[slug].html ) — so you can reference it in templates as {{params.slug}} , or inside lifecycle hooks and methods as this.get('params').slug , whether or not a given component uses preload . 是的, params对象始终在您的页面中可用(不是嵌套组件,除非您向下传递prop,而是所有顶级组件,如routes/whatever/[slug].html ),因此您可以在模板中将其引用为{{params.slug}} ,或在生命周期内使用钩子和方法this.get('params').slug ,无论给定组件是否使用preload

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM