2

我的 Svelte 组件像这样导入可读存储:

import { classes, locations, schedule } from 'stores.ts'

在stores.ts 中,我想使用$app/stores 中的page.host 动态构建获取URL。

// Note: this is not a Svelte component; it's stores.ts
import { readable } from 'svelte/store'
import { getStores } from '$app/stores'
const { page } = getStores()
let FQDN
page.subscribe(({ host }) => {
  FQDN = host
})

const getArray = async (url) => {
  const response: Response = await fetch(url)
  if (!response.ok) throw new Error(`Bad response trying to retrieve from ${url}.`)
  return await response.json()
}

const getReadableStore = (url: string) => readable([], set => {
  getArray(`http://${FQDN}${url}`)
    .then(set)
    .catch(err => console.error('Failed API call:', err))
  return () => {}
})

export const classes = getReadableStore('/api/class/public.json')
export const locations = getReadableStore('/api/location/public.json')
export const schedule = getReadableStore('/api/schedule/public.json')

第六行抛出这个错误......

错误:在 Proxy.getContext (/Users/nates/dev/shy-svelte) 的 get_current_component (/Users/nates/dev/shy-svelte/node_modules/svelte/internal/index.js:652:15) 调用外部组件初始化的函数/node_modules/svelte/internal/index.js:685:12) 在 Module.getStores (/.svelte-kit/dev/runtime/app/stores.js:17:26) 在 eval (/src/stores.ts: 6:38)在实例化模块(/Users/nates/dev/shy-svelte/node_modules/@sveltejs/kit/node_modules/vite/dist/node/chunks/dep-e9a16784.js:68197:166)

两个问题...

  1. 在组件上下文之外从 $app/stores 获取页面值的正确方法是什么?这可能吗?来自下面的回答:不,这在组件的上下文之外是不可能的。
  2. 如果我正在访问一个 SvelteKit 站点,比如说,http://localhost:3000/something或者https://example.com一个 Svelte 组件从 stores.ts 加载一个可读存储,stores.ts 中是否有办法确定加载该组件的原始页面请求(从 store.ts 加载)。 ts) 是http还是https从下面回答:不,这在stores.ts 中是不可能的——只能来自一个组件。

更新:根据反馈,我将在我的 .env 中设置一个名为 VITE_WEB_URL=http://localhost:3000 的值,并为生产系统更改它。这减少了代码行数,可能是更好的做法(欢迎评论)......

// revised stores.ts
import { readable } from 'svelte/store'

const { VITE_WEB_URL } = import.meta.env

const getArray = async (url) => {
  const response: Response = await fetch(url)
  if (!response.ok) throw new Error(`Bad response trying to retrieve from ${url}.`)
  return await response.json()
}

const getReadableStore = (url: string) => readable([], set => {
  getArray(`${VITE_WEB_URL}${url}`)
    .then(set)
    .catch(err => console.error('Failed API call:', err))
  return () => {}
})

export const classes = getReadableStore('/api/class/public.json')
export const locations = getReadableStore('/api/location/public.json')
export const schedule = getReadableStore('/api/schedule/public.json')
4

2 回答 2

2
  1. 摘自https://kit.svelte.dev/docs#modules-$app-stores

因此,存储不是自由浮动的对象:它们必须在组件初始化期间访问,就像使用 getContext 访问的任何其他内容一样。

  1. 因此,由于可读存储绑定到一个 svelte 组件的上下文,我建议您在 SvelteKit 网站的组件内订阅任何一种方式($ 或 .subscribe),然后在它发送协议值(http 或 https)作为参数更新,以便 stores.ts 将其存储在变量中。

但是,看起来 SvelteKit 没有提供协议值,所以在页面订阅中解析客户端 window.location.href 然后发送。

于 2021-06-02T17:30:13.540 回答
1
  1. 可以在任何地方引用一个苗条的商店。但是,使用 $: 简写语法只能在组件内使用。

$: BASE = `http://${$page.host}`
  1. SvelteKit 似乎确实将其委托给 fetch
于 2021-06-02T11:09:46.730 回答