Aracılığıyla paylaş


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

Not

Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 10 sürümüne bakın.

Bu makalede, statik sunucu tarafı işleme (JSstatik SSR) ve Blazor Web App ile javascript'in () nasıl yüklenecekleri açıklanı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ş gezintiyle oluşan sayfa güncellemelerini dinlemek için bir olay dinleyicisi kullanmalıdır.

Etkinlikler

Aşağıdaki olay dinleyicisi örneklerinde {CALLBACK} yer tutucusu geri çağırma fonksiyonudur.

  • Gelişmiş gezinti başlangıcı (enhancednavigationstart), gelişmiş gezinti gerçekleşmeden önce bir geri çağrıyı tetikler.

    blazor.addEventListener("enhancednavigationstart", {CALLBACK});
    
  • Gelişmiş gezinti ucu (enhancednavigationend), gelişmiş gezinti gerçekleştikten sonra geri çağırma tetikler:

    blazor.addEventListener("enhancednavigationend", {CALLBACK});
    
  • Gelişmiş gezinti sayfası yükü (enhancedload), sayfa her güncelleştiğinde, gelişmiş gezinti ve akış güncellemeleri de dahil olmak üzere bir geri çağırma tetikler:

    blazor.addEventListener("enhancedload", {CALLBACK});
    

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 kullanmalıdır:

blazor.addEventListener("enhancedload", {CALLBACK});

Önceki örnekte {CALLBACK} yer tutucusu geri çağırma fonksiyonudur.

Gelişmiş sayfa yükleme betiği örneği

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 PageScript sınıf kitaplığından (RCL) bir bileşen içerirRazor.

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.

içine Blazor Web Appaş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');
}

Razor Sınıf Kitaplığı (RCL)'ye (örnek RCL BlazorPageScriptolarak adlandırılır), JS başlatıcıolan 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);
}

Bu örnekteki modülbir başlatıcısı () olduğundan uygulamanın kök bileşenine (genellikle componennt) etiketi eklemeyin. JS başlatıcılar Blazor çerçevesi tarafından otomatik olarak algılanıp yüklenir.

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 onLoad gelişmiş gezinti de dahil olmak üzere herhangi bir gelişmiş sayfa güncelleştirmesi gerçekleştiğinde çalışıronUpdate.

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 counter bileşen başvurusu bir PageScript 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 MutationObserver kullanınJS. Daha fazla bilgi için bkz. ASP.NET Core Blazor JavaScript birlikte çalışabilirliği (JSbirlikte çalışma).

RCL kullanmadan uygulama

Bu makalede açıklanan yaklaşım, RCL'nin varlıkları uygulamaya taşınarak bir Blazor Web App'da Razor sınıf kitaplığı (RCL) kullanılmadan doğrudan uygulanabilir. Ancak, bir RCL kullanmak kolaydır çünkü RCL, kuruluş genelindeki Blazor uygulamaları tarafından kullanılmak üzere bir NuGet paketine dönüştürülebilir.

Varlıkları bir taşırsanız, modülü () başlatıcılar için dosya adlandırma kuralları başına uygulamayla eşleşecek şekilde yeniden adlandırdığınızdan emin olun. Dosya doğru adlandırılmıyorsa Blazor modülü algılayıp yükleyemez ve uygulama başlatıldığında afterWebStarted olayı otomatik olarak yürütülmüyor.