首页 > 解决方案 > 将数据从 .NET razor 视图传递到 Svelte

问题描述

我有一个预先存在的 CMS 应用程序,它在 C# .NET MVC 上运行,其中 CMS API 大量用于业务逻辑并将数据转发到 Razor 文件。该应用程序已经将 gulp 和 rollup 用于预先存在的 vanilla JavaScript 模块。我想探索在此 Razor 组件级别使用 Svelte 的可能性,并在页面上多次呈现 Razor 视图时将其作为内部 svelte 组件启动。

使用 react,可以将自定义元素定义为 web 组件,然后在 razor 文件中使用,从而允许传递属性。我发现在 Svelte 中使用自定义元素 API很麻烦,因为我的应用程序使用 Bootstrap 并且自定义元素使用 shadow dom,因此它们没有获得任何应用程序样式。似乎还有一个关于 Svelte 自定义元素的问题的运行列表,我希望远离企业应用程序。

我在我的应用程序中设置了两个普通的 Svelte 组件:NotificationTray.svelteNotificationUpdateButton.svelte,以及一个典型的store.js

NotificationTray.svelte

<script context="module">
  export const selector = '.notification-tray';
</script>
<script>
  export let count = 0;

  import {
    notificationCount
  } from './stores.js'

</script>

<div class="notification-tray__container position-relative ms-3">
  <i class="bi bi-bell"></i>
  <span class="count position-absolute rounded-circle lh-1">{ count + $notificationCount }</span>
</div>

NotificationUpdateButton.svelte

<script context="module">
  export const selectorTwo = '.notification-btn';
</script>
<script>
  export let btnLabel = '';

  import {
    notificationCount
  } from './stores.js'

  const updateNotificationCount = () => {
    notificationCount.update(count => count + 1);
  }

</script>

<input type="button" value="{btnLabel}" on:click={updateNotificationCount}>

main.js(入口点)

import NotificationTray, { selector } from './svelte/NotificationTray.svelte';
import NotificationUpdateButton, { selectorTwo } from './svelte/NotificationUpdateButton.svelte';

// helpers
function toObject(el) {
  let result = {};
  for (let attribute of el.attributes) {
      let tempVal = isNaN(attribute.value) ? attribute.value : parseFloat(attribute.value);
      result[camelCase(attribute.name)] = tempVal;
  }
  return result;
}

function camelCase(name, delim = '-') {
  const pattern = new RegExp((delim + "([a-z])"), "g")
  return name.replace(pattern, (match, capture) => capture.toUpperCase())
}

// initiate svelte components
[...document.querySelectorAll(selector)].forEach(el => {
  new NotificationTray({
    target: el,
    props: toObject(el)
  });
});

[...document.querySelectorAll(selectorTwo)].forEach(el => {
  new NotificationUpdateButton({
    target: el,
    props: toObject(el)
  });
});

store.js

import { writable } from "svelte/store";

export const notificationCount = writable(0);

Index.cshtml - 显示带有要由 Svelte 初始化的选择器的元素

<div class="notification-tray" count="@Model.NotificationCount"></div>
<div class="notification-btn" btn-label="@Model.BtnLabel_IncreaseCount"></div>

这种方法有效(并且我已经使用多个“通知-btn”元素进行了测试,它们都更新了通知托盘),但我很想知道是否有比我提出的更好的实现方法main.js,是否它是一些我不知道的苗条 api 或清理 main.js,这样我就不必继续执行 selectorThree、selectorFour 等。

标签: javascriptrazorsvelte

解决方案


推荐阅读