我对Sapper / Svelte

时间:2018-03-02 21:02:00

标签: javascript node.js angular frameworks 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>

enter image description here

现在我的问题:

  1. 我注意到我无法#each通过我的对象。我必须循环其键。如果我可以做这样的事情会很好:

    {{#each info.attributes as attribute}}

    {{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,我想知道什么。

  7. 让一些专家以最好的方式重写我所做的一切真的很酷,可能会解决我的一些问题。

1 个答案:

答案 0 :(得分:2)

  1. Svelte只会迭代类似数组的对象,因为它不可能保证对象的一致行为 - 它会抛出最好在应用程序级别解决的各种边缘情况。你可以做这种事情,只使用标准的JavaScript习语:
  2. {{#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解决方案是在preload中获取一些JSON:
    2. preload({ params, query }) {
        return fetch(`/i18n/${locale}.json`)
          .then(r => r.json())
          .then(dict => {
            return { dict };
          });
      }
      

      然后,您可以在模板中引用{{dict["hello"]}}之类的内容。更复杂的解决方案只会加载当前页面所需的字符串,并会缓存所有内容等,但基本思路是相同的。

      1. 我想你可以这样做:
      2. // 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/#resolve-modules

        2. 这是使用双向绑定的好地方:

        3. {{#each Object.values(info.attributes) as attr}}
            <p>{{attr.description}} <input bind:value=organization_name /></p>
          {{/each}}
          
          1. 是的,params对象在您的网页中始终可用(不是嵌套组件,除非您传递了prop,但是所有顶级组件都是routes/whatever/[slug].html) - 因此您可以引用它在模板中为{{params.slug}},或在生命周期挂钩和方法内为this.get('params').slug,无论给定组件是否使用preload