Aracılığıyla paylaş


Statik sunucu tarafı işleme (statik SSR) ile ASP.NET Core Blazor JavaScript

Bu makalede, bir Web Uygulamasında statik sunucu tarafı işleme (JSstatik SSR) Blazor ve gelişmiş gezinti ile JavaScript'in () nasıl yüklenecekleri açıklanmaktadır.

Bazı uygulamalar, her sayfaya özgü başlatma görevlerini gerçekleştirmeye bağımlıdır JS . Kullanıcının sayfanın tamamını yeniden yüklemesini önleyen gelişmiş gezinti özelliği kullanılırken Blazor, sayfaya özgü JS özelliği her gelişmiş sayfa gezintisi gerçekleştiğinde beklendiği gibi yeniden yürütülmeyebilir.

Bu sorunu önlemek için, bileşene uygulanan düzen dosyasının dışına yerleştirilmiş sayfaya özgü <script> öğelere güvenmenizi önermeyiz. Bunun yerine, betikler başlatma mantığını gerçekleştirmek için bir afterWebStartedJS başlatıcı kaydetmeli ve gelişmiş gezintinin neden olduğu sayfa güncelleştirmelerini dinlemek için bir olay dinleyicisi (blazor.addEventListener("enhancedload", callback)) kullanmalıdır.

Aşağıdaki örnekte, gelişmiş gezintiye sahip statik olarak işlenmiş bir sayfa başlangıçta yüklendiğinde veya güncelleştirildiğinde çalışacak şekilde kod yapılandırmanın JS bir yolu gösterilmektedir.

Aşağıdaki PageWithScript bileşen örneği, uygulamadaki betiklerin statik SSR ve gelişmiş gezinti ile çalıştırılmasını gerektiren bir bileşendir. Aşağıdaki bileşen örneği, bu makalenin devamında çözüme eklenen bir Razor sınıf kitaplığından (RCL) bir bileşen içerirPageScript.

Components/Pages/PageWithScript.razor:

@page "/page-with-script"
@using BlazorPageScript

<PageTitle>Enhanced Load Script Example</PageTitle>

<PageScript Src="./Components/Pages/PageWithScript.razor.js" />

Welcome to my page.

Web Uygulaması'nda Blazor aşağıdaki birlikte bulunan JS dosyayı ekleyin:

  • onLoad , betik sayfaya eklendiğinde çağrılır.
  • onUpdate , gelişmiş bir güncelleştirmeden sonra betik sayfada hala mevcut olduğunda çağrılır.
  • onDispose , gelişmiş bir güncelleştirmeden sonra betik sayfadan kaldırıldığında çağrılır.

Components/Pages/PageWithScript.razor.js:

export function onLoad() {
  console.log('Loaded');
}

export function onUpdate() {
  console.log('Updated');
}

export function onDispose() {
  console.log('Disposed');
}

Sınıf Razor Kitaplığı'nda (RCL) (örnek RCL adlı BlazorPageScript), aşağıdaki modülü ekleyin.

wwwroot/BlazorPageScript.lib.module.js:

const pageScriptInfoBySrc = new Map();

function registerPageScriptElement(src) {
  if (!src) {
    throw new Error('Must provide a non-empty value for the "src" attribute.');
  }

  let pageScriptInfo = pageScriptInfoBySrc.get(src);

  if (pageScriptInfo) {
    pageScriptInfo.referenceCount++;
  } else {
    pageScriptInfo = { referenceCount: 1, module: null };
    pageScriptInfoBySrc.set(src, pageScriptInfo);
    initializePageScriptModule(src, pageScriptInfo);
  }
}

function unregisterPageScriptElement(src) {
  if (!src) {
    return;
  }

  const pageScriptInfo = pageScriptInfoBySrc.get(src);
  
  if (!pageScriptInfo) {
    return;
  }

  pageScriptInfo.referenceCount--;
}

async function initializePageScriptModule(src, pageScriptInfo) {
  if (src.startsWith("./")) {
    src = new URL(src.substr(2), document.baseURI).toString();
  }

  const module = await import(src);

  if (pageScriptInfo.referenceCount <= 0) {
    return;
  }

  pageScriptInfo.module = module;
  module.onLoad?.();
  module.onUpdate?.();
}

function onEnhancedLoad() {
  for (const [src, { module, referenceCount }] of pageScriptInfoBySrc) {
    if (referenceCount <= 0) {
      module?.onDispose?.();
      pageScriptInfoBySrc.delete(src);
    }
  }

  for (const { module } of pageScriptInfoBySrc.values()) {
    module?.onUpdate?.();
  }
}

export function afterWebStarted(blazor) {
  customElements.define('page-script', class extends HTMLElement {
    static observedAttributes = ['src'];

    attributeChangedCallback(name, oldValue, newValue) {
      if (name !== 'src') {
        return;
      }

      this.src = newValue;
      unregisterPageScriptElement(oldValue);
      registerPageScriptElement(newValue);
    }

    disconnectedCallback() {
      unregisterPageScriptElement(this.src);
    }
  });

  blazor.addEventListener('enhancedload', onEnhancedLoad);
}

RCL'ye aşağıdaki PageScript bileşeni ekleyin.

PageScript.razor:

<page-script src="@Src"></page-script>

@code {
    [Parameter]
    [EditorRequired]
    public string Src { get; set; } = default!;
}

PageScript Bileşen normalde sayfanın en üst düzeyinde çalışır.

Bileşeni bir uygulamanın düzenine PageScript yerleştirirseniz (örneğin, MainLayout.razor), düzeni kullanan sayfalar arasında paylaşılan PageScript bir bileşenle sonuçlanırsa, bileşen yalnızca tam sayfa yeniden yükledikten sonra ve onUpdate gelişmiş gezinti de dahil olmak üzere herhangi bir gelişmiş sayfa güncelleştirmesi gerçekleştiğinde çalışıronLoad.

Aynı modülü sayfalar arasında yeniden kullanmak, ancak onLoad her sayfada ve onDispose geri çağırmalarının çağrılması için, betiğin sonuna bir sorgu dizesi ekleyerek farklı bir modül olarak tanınmasını sağlayın. Bir uygulama, sorgu dizesi değeri olarak bileşenin adını kullanma kuralını benimseyebilir. Aşağıdaki örnekte, bu PageScript bileşen başvurusu bir Counter bileşene yerleştirildiğinden sorgu dizesi "counter" şeklindedir. Bu yalnızca bir öneridir ve tercih ettiğiniz sorgu dizesi düzenini kullanabilirsiniz.

<PageScript Src="./Components/Pages/PageWithScript.razor.js?counter" />

Belirli DOM öğelerindeki değişiklikleri izlemek için istemcideki içindeki desenini JS kullanınMutationObserver. Daha fazla bilgi için bkz. ASP.NET Core Blazor JavaScript birlikte çalışabilirliği (JSbirlikte çalışma).

RCL kullanmadan örnek uygulama

Bu makalede açıklanan yaklaşım, sınıf kitaplığı (RCL) kullanılmadan doğrudan bir BlazorRazor Web Uygulamasında uygulanabilir. Örnek için bkz . ASP.NET Core Blazor Web App'te TOTP kimlik doğrulayıcı uygulamaları için QR kodu oluşturmayı etkinleştirme.