/
githubmirror
/
angular
Обзор
Документация
Войти
/
githubmirror
/
angular
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
adev/src/app/features/playground/playground.component.ts
117 строк
4 KB
SkyZeroZx
docs(docs-infra): use signals & improve types
08 май 2026, 03:17
08 май 2026, 03:17
a0b998e
Код
Авторство
О чём код?
/*! * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.dev/license */ import {CdkMenu, CdkMenuItem, CdkMenuTrigger} from '@angular/cdk/menu'; import {isPlatformServer, NgComponentOutlet} from '@angular/common'; import { Component, DestroyRef, effect, EnvironmentInjector, inject, injectAsync, input, PLATFORM_ID, signal, Type, } from '@angular/core'; import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; import {IconComponent, PlaygroundTemplate} from '@angular/docs'; import {forkJoin, switchMap, tap} from 'rxjs'; import {injectNodeRuntimeSandbox} from '../../editor/index'; import type {NodeRuntimeSandbox} from '../../editor/node-runtime-sandbox.service'; import {ActivatedRoute, Router} from '@angular/router'; import PLAYGROUND_ROUTE_DATA_JSON from '../../../../src/assets/tutorials/playground/routes.json'; @Component({ selector: 'adev-playground', imports: [NgComponentOutlet, IconComponent, CdkMenu, CdkMenuItem, CdkMenuTrigger], templateUrl: './playground.component.html', styleUrls: ['./playground.component.scss', '../tutorial/tutorial-navigation.scss'], }) export default class PlaygroundComponent { readonly templateId = input<string | undefined>(); private readonly environmentInjector = inject(EnvironmentInjector); private readonly destroyRef = inject(DestroyRef); private readonly isServer = isPlatformServer(inject(PLATFORM_ID)); private readonly router = inject(Router); private readonly route = inject(ActivatedRoute); private editorTutorialManager = injectAsync(() => import('../../editor/index').then((c) => c.EmbeddedTutorialManager), ); readonly templates: PlaygroundTemplate[] = PLAYGROUND_ROUTE_DATA_JSON.templates; readonly defaultTemplate = PLAYGROUND_ROUTE_DATA_JSON.defaultTemplate; readonly starterTemplate = PLAYGROUND_ROUTE_DATA_JSON.starterTemplate; protected nodeRuntimeSandbox?: NodeRuntimeSandbox; protected embeddedEditorComponent = signal<Type<unknown> | null>(null); protected selectedTemplate: PlaygroundTemplate = this.defaultTemplate; private readonly isSandboxReady = signal(false); constructor() { if (this.isServer) { return; } effect(() => { const foundTemplate = this.templates.find((t) => t.id === this.templateId()); this.changeTemplate(foundTemplate ?? this.defaultTemplate); }); // If using `async-await`, `this` will be captured until the function is executed // and completed, which can lead to a memory leak if the user navigates away from // the playground component to another page. forkJoin({ nodeRuntimeSandbox: injectNodeRuntimeSandbox(this.environmentInjector), embeddedEditorComponent: import('../../editor/index').then((c) => c.EmbeddedEditor), }) .pipe( tap(({nodeRuntimeSandbox, embeddedEditorComponent}) => { this.nodeRuntimeSandbox = nodeRuntimeSandbox; this.embeddedEditorComponent.set(embeddedEditorComponent); }), switchMap(() => this.loadTemplate(this.selectedTemplate.path)), takeUntilDestroyed(this.destroyRef), ) .subscribe(() => { this.nodeRuntimeSandbox?.init(); this.isSandboxReady.set(true); }); } async newProject() { await this.loadTemplate(this.starterTemplate.path); } async changeTemplate(template: PlaygroundTemplate): Promise<void> { this.router.navigate([], { relativeTo: this.route, queryParams: {templateId: template.id}, replaceUrl: true, }); this.selectedTemplate = template; await this.loadTemplate(template.path); if (this.isSandboxReady()) { await this.nodeRuntimeSandbox?.reset(); } } private async loadTemplate(tutorialPath: string) { try { const embeddedTutorialManager = await this.editorTutorialManager(); await embeddedTutorialManager.fetchAndSetTutorialFiles(tutorialPath); } catch (err) { console.error('Failed to load tutorial files', err); } } }