1

我创建了一个包含表单的视图,该表单的控件绑定到模型对象上的属性,该对象也由其他视图共享)。我试图弄清楚是否真的有必要或推荐使用 Store 范例。

例如,模型看起来有点像:

model = { 
   foo: undefined,
   bar: undefined,
   baz: undefined
}

...并且 UI 将通过以下方式将各种输入绑定到模型:

//example.svelte
<script>
   import { exampleModel } from "./models.js";
</script>

<h2>Has foo?</h2>
<label for="input_foo_t">yes</label>
<input id="input_foo_t" type="radio" bind:group={exampleModel.foo} value={true}/>

<label for="input_foo_f">no</label>
<input id="input_foo_f" type="radio" bind:group={exampleModel.foo} value={false}/>

<h2>Has bar?</h2>
<label for="input_bar_t">yes</label>
<input id="input_bar_t" type="radio" bind:group={exampleModel.bar} value={true}/>

<label for="input_bar_f">no</label>
<input id="input_bar_f" type="radio" bind:group={exampleModel.bar} value={false}/>

理想情况下,我想将这些论文作为一个整体。从我看到的所有示例中,没有这样的东西。Svelte Stores 的目的是提供超细粒度、可共享的数据,以便我们基本上“存储”单个值吗?或者是否有示例显示在商店范式中使用的模型对象之类的东西?我是否错过了一些我需要通过使用 Svelte Store(类似于 Angular 的摘要)来利用的生命周期过程?

4

2 回答 2

6

您当然可以为此使用商店:

// models.js
import { writable } from 'svelte/store';

export const exampleModel = writable({
  foo: undefined,
  bar: undefined,
  baz: undefined,
});
//example.svelte
<script>
   import { exampleModel } from "./models.js";
</script>

<h2>Has foo?</h2>
<label for="input_foo_t">yes</label>
<input id="input_foo_t" type="radio" bind:group={$exampleModel.foo} value={true}/>
<!-- etc -->

话虽如此,最好不要有巨大的模型,因为修改一个属性会导致检查它的所有依赖项(即,如果您更改$exampleModel.foo,对的引用$exampleModel.bar也将被更新,因为就 Svelte 而言$exampleModel,更改的东西) . 这通常不是一个真正的问题,但需要注意。避免这种情况的替代方法是具有更细化的值:

// models.js
export const foo = writable();
export const bar = writable();
export const baz = writable();
于 2019-10-18T13:17:43.273 回答
1

我创建了两个示例来演示 Rich 所说的内容。

  1. 第一个使用包含所有三个变量的单个模型(具有深度)(此处演示:Svelte Store Granularity (Ver 1 Single Model)

    单击复选框以更改单个变量。统计的状态变化(右侧)表明所有三个变量都被错误地认为已被反射性改变:-(

    <script>
      const fooChangeCount = createReflectiveCounter();
      const barChangeCount = createReflectiveCounter();
      const bazChangeCount = createReflectiveCounter();
    
      // monitor store-based state changes
      $: fooChangeCount.monitor($model.foo);
      $: barChangeCount.monitor($model.bar);
      $: bazChangeCount.monitor($model.baz);
    
      const reset = () => {
        fooChangeCount.reset();
        barChangeCount.reset();
        bazChangeCount.reset();
      };
    </script>
    
    <h2>Svelte Store Granularity</h2>
    <h4><i>(Ver 1 Single Model)</i></h4>
    
    <label><input type=checkbox bind:checked={$model.foo}> foo: (state changed {$fooChangeCount} times)</label>
    <label><input type=checkbox bind:checked={$model.bar}> bar: (state changed {$barChangeCount} times)</label>
    <label><input type=checkbox bind:checked={$model.baz}> baz: (state changed {$bazChangeCount} times)</label>
    
    <p><i>click to change each var: <b>state changes tallied to right</b></i></p>
    <button on:click={reset}>Reset Counts</button>
    
    <script context="module">
      import {writable} from 'svelte/store';
    
      const model = writable({
        foo: undefined,
        bar: undefined,
        baz: undefined,
      });
    
      function createReflectiveCounter() {
        // our base writable store
        // ... -1 accounts for our initial monitor reflection (bumping it to 0)
        const {subscribe, set, update} = writable(-1);
    
        // expose our newly created custom store
        return {
          subscribe,
          monitor() {
            update((count) => count + 1); // increment our count
            return '';                    // see JavaDoc
          },
          reset: () => set(0)
        };
      }
    </script>
    
  2. 第二个使用多个模型,一个用于三个变量中的每一个(此处演示:Svelte Store Granularity (Ver 2 Multiple Models)

    在这种情况下,计数状态更改(向右)现在正确地表明只有实际更改的变量被认为是自反的 :-)

    <script>
      const fooChangeCount = createReflectiveCounter();
      const barChangeCount = createReflectiveCounter();
      const bazChangeCount = createReflectiveCounter();
    
      // monitor store-based state changes
      $: fooChangeCount.monitor($foo);
      $: barChangeCount.monitor($bar);
      $: bazChangeCount.monitor($baz);
    
      const reset = () => {
        fooChangeCount.reset();
        barChangeCount.reset();
        bazChangeCount.reset();
      };
    </script>
    
    
    <h2>Svelte Store Granularity</h2>
    <h4><i>(Ver 2 Multiple Models)</i></h4>
    
    <label><input type=checkbox bind:checked={$foo}> foo: (state changed {$fooChangeCount} times)</label>
    <label><input type=checkbox bind:checked={$bar}> bar: (state changed {$barChangeCount} times)</label>
    <label><input type=checkbox bind:checked={$baz}> baz: (state changed {$bazChangeCount} times)</label>
    
    <!-- Diagnostic: monitor store-based state changes -->
    <p><i>click to change each var: <b>state changes tallied to right</b></i></p>
    <button on:click={reset}>Reset Counts</button>
    
    
    <script context="module">
      import {writable} from 'svelte/store';
    
      const foo = writable();
      const bar = writable();
      const baz = writable();
    
      function createReflectiveCounter() {
        // our base writable store
        // ... -1 accounts for our initial monitor reflection (bumping it to 0)
        const {subscribe, set, update} = writable(-1);
    
        // expose our newly created custom store
        return {
          subscribe,
          monitor() {
            update((count) => count + 1); // increment our count
            return '';                    // see JavaDoc
          },
          reset: () => set(0)
        };
      }
    </script>
    

希望这可以帮助!

</Kevin>

于 2020-06-26T18:32:11.190 回答