亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄
裝飾器與元資料
Angular 中的裝飾器和元資料
總結(jié)
首頁 web前端 js教程 聊聊Angular中的元資料(Metadata)和裝飾器(Decorator)

聊聊Angular中的元資料(Metadata)和裝飾器(Decorator)

Feb 28, 2022 am 11:10 AM
angular

這篇文章繼續(xù)Angular的學(xué)習(xí),帶大家了解一下Angular中的元資料和裝飾器,簡單了解一下他們的用法,希望對大家有所幫助!

聊聊Angular中的元資料(Metadata)和裝飾器(Decorator)

作為「為大型前端專案」而設(shè)計的前端框架,Angular 其實有許多值得參考和學(xué)習(xí)的設(shè)計,本系列主要用於研究這些設(shè)計和功能的實現(xiàn)原理。本文主要圍繞在 Angular 中隨處可見的元數(shù)據(jù),來進行介紹。 【相關(guān)教學(xué)推薦:《angular教學(xué)》】

#裝飾器是使用 Angular 進行開發(fā)時的核心概念。在 Angular 中,裝飾器用於為類別或?qū)傩愿郊釉獢?shù)據(jù),來讓自己知道那些類別或?qū)傩缘暮x,以及該如何處理它們。

裝飾器與元資料

不管是裝飾器還是元數(shù)據(jù),都不是 Angular 提出的概念。因此,我們先來簡單了解一下。

元資料(Metadata)

在通用的概念中,元資料是描述使用者資料的資料。它總結(jié)了有關(guān)數(shù)據(jù)的基本信息,可以使查找和使用特定數(shù)據(jù)實例更加容易。例如,作者,建立日期,修改日期和文件大小是非?;镜奈臋n元資料的範例。

在用於類別的場景下,元資料用於裝飾類,來描述類別的定義和行為,以便可以配置類別的預(yù)期行為。

裝飾器(Decorator)

#裝飾器是JavaScript 的語言特性,是位於階段2(stage 2)的試驗特性。

裝飾器是定義期間在類,類元素或其他 JavaScript 語法形式上呼叫的函數(shù)。

裝飾器有三個主要功能:

  • 可以用具有相同語意的匹配值取代正在修飾的值。 (例如,裝飾器可以將方法替換為另一種方法,將一個字段替換為另一個字段,將一個類替換為另一個類,等等)。

  • 可以將元資料與正在修飾的值相關(guān)聯(lián);可以從外部讀取此元數(shù)據(jù),並將其用於元程式設(shè)計和自我檢查。

  • 可以透過元資料提供對正在修飾的值的存取。對於公共值,他們可以透過值名稱來實現(xiàn);對於私有值,它們接收存取器函數(shù),然後可以選擇共用它們。

本質(zhì)上,裝飾器可用於對值進行元編程和向其添加功能,而無需從根本上改變其外部行為。

更多的內(nèi)容,可以參考 tc39/proposal-decorators 提案。

Angular 中的裝飾器和元資料

我們在開發(fā) Angular 應(yīng)用程式時,不管是元件、指令,或是服務(wù)、模組等,都需要透過裝飾器來進行定義和開發(fā)。裝飾器會出現(xiàn)在類別定義的緊前方,用來聲明該類別具有指定的類型,並且提供適合該類型的元資料。

例如,我們可以用下列裝飾器來宣告Angular 的類別:@Component()、@Directive()、@Pipe()@Injectable()、@NgModule()。

使用裝飾器和元資料來改變類別的行為

#以@Component()為例,該裝飾器的作用包括:

  • 將類別標記為Angular 元件。

  • 提供可配置的元數(shù)據(jù),用來決定在執(zhí)行時應(yīng)如何處理、實例化和使用該元件。

關(guān)於@Component()該如何使用可以參考,這裡不多介紹。讓我們來看看這個裝飾器的定義:

// 提供 Angular 組件的配置元數(shù)據(jù)接口定義
// Angular 中,組件是指令的子集,始終與模板相關(guān)聯(lián)
export interface Component extends Directive {
  // changeDetection 用于此組件的變更檢測策略
  // 實例化組件時,Angular 將創(chuàng)建一個更改檢測器,該更改檢測器負責(zé)傳播組件的綁定。
  changeDetection?: ChangeDetectionStrategy;
  // 定義對其視圖 DOM 子對象可見的可注入對象的集合
  viewProviders?: Provider[];
  // 包含組件的模塊的模塊ID,該組件必須能夠解析模板和樣式的相對 URL
  moduleId?: string;
  ...
  // 模板和 CSS 樣式的封裝策略
  encapsulation?: ViewEncapsulation;
  // 覆蓋默認的插值起始和終止定界符(`{{`和`}}`)
  interpolation?: [string, string];
}

// 組件裝飾器和元數(shù)據(jù)
export const Component: ComponentDecorator = makeDecorator(
    'Component',
    // 使用默認的 CheckAlways 策略,在該策略中,更改檢測是自動進行的,直到明確停用為止。
    (c: Component = {}) => ({changeDetection: ChangeDetectionStrategy.Default, ...c}),
    Directive, undefined,
    (type: Type<any>, meta: Component) => SWITCH_COMPILE_COMPONENT(type, meta));

以上便是元件裝飾、元件元資料的定義,我們來看看裝飾器的創(chuàng)建過程。

裝飾器的建立過程

我們可以從原始碼中找到,元件和指令的裝飾器都會透過makeDecorator() 來產(chǎn)生:

export function makeDecorator<T>(
    name: string, props?: (...args: any[]) => any, parentClass?: any, // 裝飾器名字和屬性
    additionalProcessing?: (type: Type<T>) => void,
    typeFn?: (type: Type<T>, ...args: any[]) => void):
    {new (...args: any[]): any; (...args: any[]): any; (...args: any[]): (cls: any) => any;} {
  // noSideEffects 用于確認閉包編譯器包裝的函數(shù)沒有副作用
  return noSideEffects(() => { 
    const metaCtor = makeMetadataCtor(props);
    // 裝飾器工廠
    function DecoratorFactory(
        this: unknown|typeof DecoratorFactory, ...args: any[]): (cls: Type<T>) => any {
      if (this instanceof DecoratorFactory) {
        // 賦值元數(shù)據(jù)
        metaCtor.call(this, ...args);
        return this as typeof DecoratorFactory;
      }
      // 創(chuàng)建裝飾器工廠
      const annotationInstance = new (DecoratorFactory as any)(...args);
      return function TypeDecorator(cls: Type<T>) {
        // 編譯類
        if (typeFn) typeFn(cls, ...args);
        // 使用 Object.defineProperty 很重要,因為它會創(chuàng)建不可枚舉的屬性,從而防止該屬性在子類化過程中被復(fù)制。
        const annotations = cls.hasOwnProperty(ANNOTATIONS) ?
            (cls as any)[ANNOTATIONS] :
            Object.defineProperty(cls, ANNOTATIONS, {value: []})[ANNOTATIONS];
        annotations.push(annotationInstance);
        // 特定邏輯的執(zhí)行
        if (additionalProcessing) additionalProcessing(cls);

        return cls;
      };
    }
    if (parentClass) {
      // 繼承父類
      DecoratorFactory.prototype = Object.create(parentClass.prototype);
    }
    DecoratorFactory.prototype.ngMetadataName = name;
    (DecoratorFactory as any).annotationCls = DecoratorFactory;
    return DecoratorFactory as any;
  });
}

在上面的範例中,我們透過makeDecorator()產(chǎn)生了一個用於定義元件的Component裝飾器工廠。當(dāng)使用@Component()建立元件時,Angular 會根據(jù)元資料來編譯元件。

根據(jù)裝飾器元資料編譯元件

Angular 會根據(jù)該裝飾器元數(shù)據(jù),來編譯Angular 元件,然後將產(chǎn)生的元件定義(?cmp)修補到元件類型上:

export function compileComponent(type: Type<any>, metadata: Component): void {
  // 初始化 ngDevMode
  (typeof ngDevMode === &#39;undefined&#39; || ngDevMode) && initNgDevMode();
  let ngComponentDef: any = null;
  // 元數(shù)據(jù)可能具有需要解析的資源
  maybeQueueResolutionOfComponentResources(type, metadata);
  // 這里使用的功能與指令相同,因為這只是創(chuàng)建 ngFactoryDef 所需的元數(shù)據(jù)的子集
  addDirectiveFactoryDef(type, metadata);
  Object.defineProperty(type, NG_COMP_DEF, {
    get: () => {
      if (ngComponentDef === null) {
        const compiler = getCompilerFacade();
        // 根據(jù)元數(shù)據(jù)解析組件
        if (componentNeedsResolution(metadata)) {
          ...
          // 異常處理
        }
        ...
        // 創(chuàng)建編譯組件需要的完整元數(shù)據(jù)
        const templateUrl = metadata.templateUrl || `ng:///${type.name}/template.html`;
        const meta: R3ComponentMetadataFacade = {
          ...directiveMetadata(type, metadata),
          typeSourceSpan: compiler.createParseSourceSpan(&#39;Component&#39;, type.name, templateUrl),
          template: metadata.template || &#39;&#39;,
          preserveWhitespaces,
          styles: metadata.styles || EMPTY_ARRAY,
          animations: metadata.animations,
          directives: [],
          changeDetection: metadata.changeDetection,
          pipes: new Map(),
          encapsulation,
          interpolation: metadata.interpolation,
          viewProviders: metadata.viewProviders || null,
        };
        // 編譯過程需要計算深度,以便確認編譯是否最終完成
        compilationDepth++;
        try {
          if (meta.usesInheritance) {
            addDirectiveDefToUndecoratedParents(type);
          }
          // 根據(jù)模板、環(huán)境和組件需要的元數(shù)據(jù),來編譯組件
          ngComponentDef = compiler.compileComponent(angularCoreEnv, templateUrl, meta);
        } finally {
          // 即使編譯失敗,也請確保減少編譯深度
          compilationDepth--;
        }
        if (compilationDepth === 0) {
          // 當(dāng)執(zhí)行 NgModule 裝飾器時,我們將模塊定義加入隊列,以便僅在所有聲明都已解析的情況下才將隊列出隊,并將其自身作為模塊作用域添加到其所有聲明中
          // 此調(diào)用運行檢查以查看隊列中的任何模塊是否可以出隊,并將范圍添加到它們的聲明中
          flushModuleScopingQueueAsMuchAsPossible();
        }
        // 如果組件編譯是異步的,則聲明該組件的 @NgModule 批注可以執(zhí)行并在組件類型上設(shè)置 ngSelectorScope 屬性
        // 這允許組件在完成編譯后,使用模塊中的 directiveDefs 對其自身進行修補
        if (hasSelectorScope(type)) {
          const scopes = transitiveScopesFor(type.ngSelectorScope);
          patchComponentDefWithScope(ngComponentDef, scopes);
        }
      }
      return ngComponentDef;
    },
    ...
  });
}

編譯組件的過程可能是異步的(比如需要解析組件模板或其他資源的 URL)。如果編譯不是立即進行的,compileComponent會將資源解析加入到全局隊列中,并且將無法返回?cmp,直到通過調(diào)用resolveComponentResources解決了全局隊列為止。

編譯過程中的元數(shù)據(jù)

元數(shù)據(jù)是有關(guān)類的信息,但它不是類的屬性。因此,用于配置類的定義和行為的這些數(shù)據(jù),不應(yīng)該存儲在該類的實例中,我們還需要在其他地方保存此數(shù)據(jù)。

在 Angular 中,編譯過程產(chǎn)生的元數(shù)據(jù),會使用CompileMetadataResolver來進行管理和維護,這里我們主要看指令(組件)相關(guān)的邏輯:

export class CompileMetadataResolver {
  private _nonNormalizedDirectiveCache =
      new Map<Type, {annotation: Directive, metadata: cpl.CompileDirectiveMetadata}>();
  // 使用 Map 的方式來保存
  private _directiveCache = new Map<Type, cpl.CompileDirectiveMetadata>(); 
  private _summaryCache = new Map<Type, cpl.CompileTypeSummary|null>();
  private _pipeCache = new Map<Type, cpl.CompilePipeMetadata>();
  private _ngModuleCache = new Map<Type, cpl.CompileNgModuleMetadata>();
  private _ngModuleOfTypes = new Map<Type, Type>();
  private _shallowModuleCache = new Map<Type, cpl.CompileShallowModuleMetadata>();

  constructor(
      private _config: CompilerConfig, private _htmlParser: HtmlParser,
      private _ngModuleResolver: NgModuleResolver, private _directiveResolver: DirectiveResolver,
      private _pipeResolver: PipeResolver, private _summaryResolver: SummaryResolver<any>,
      private _schemaRegistry: ElementSchemaRegistry,
      private _directiveNormalizer: DirectiveNormalizer, private _console: Console,
      private _staticSymbolCache: StaticSymbolCache, private _reflector: CompileReflector,
      private _errorCollector?: ErrorCollector) {}
  // 清除特定某個指令的元數(shù)據(jù)
  clearCacheFor(type: Type) {
    const dirMeta = this._directiveCache.get(type);
    this._directiveCache.delete(type);
    ...
  }
  // 清除所有元數(shù)據(jù)
  clearCache(): void {
    this._directiveCache.clear();
    ...
  }
  /**
   * 加載 NgModule 中,已聲明的指令和的管道
   */
  loadNgModuleDirectiveAndPipeMetadata(moduleType: any, isSync: boolean, throwIfNotFound = true):
      Promise<any> {
    const ngModule = this.getNgModuleMetadata(moduleType, throwIfNotFound);
    const loading: Promise<any>[] = [];
    if (ngModule) {
      ngModule.declaredDirectives.forEach((id) => {
        const promise = this.loadDirectiveMetadata(moduleType, id.reference, isSync);
        if (promise) {
          loading.push(promise);
        }
      });
      ngModule.declaredPipes.forEach((id) => this._loadPipeMetadata(id.reference));
    }
    return Promise.all(loading);
  }
  // 加載指令(組件)元數(shù)據(jù)
  loadDirectiveMetadata(ngModuleType: any, directiveType: any, isSync: boolean): SyncAsync<null> {
    // 若已加載,則直接返回
    if (this._directiveCache.has(directiveType)) {
      return null;
    }
    directiveType = resolveForwardRef(directiveType);
    const {annotation, metadata} = this.getNonNormalizedDirectiveMetadata(directiveType)!;
    // 創(chuàng)建指令(組件)元數(shù)據(jù)
    const createDirectiveMetadata = (templateMetadata: cpl.CompileTemplateMetadata|null) => {
      const normalizedDirMeta = new cpl.CompileDirectiveMetadata({
        isHost: false,
        type: metadata.type,
        isComponent: metadata.isComponent,
        selector: metadata.selector,
        exportAs: metadata.exportAs,
        changeDetection: metadata.changeDetection,
        inputs: metadata.inputs,
        outputs: metadata.outputs,
        hostListeners: metadata.hostListeners,
        hostProperties: metadata.hostProperties,
        hostAttributes: metadata.hostAttributes,
        providers: metadata.providers,
        viewProviders: metadata.viewProviders,
        queries: metadata.queries,
        guards: metadata.guards,
        viewQueries: metadata.viewQueries,
        entryComponents: metadata.entryComponents,
        componentViewType: metadata.componentViewType,
        rendererType: metadata.rendererType,
        componentFactory: metadata.componentFactory,
        template: templateMetadata
      });
      if (templateMetadata) {
        this.initComponentFactory(metadata.componentFactory!, templateMetadata.ngContentSelectors);
      }
      // 存儲完整的元數(shù)據(jù)信息,以及元數(shù)據(jù)摘要信息
      this._directiveCache.set(directiveType, normalizedDirMeta);
      this._summaryCache.set(directiveType, normalizedDirMeta.toSummary());
      return null;
    };

    if (metadata.isComponent) {
      // 如果是組件,該過程可能為異步過程,則需要等待異步過程結(jié)束后的模板返回
      const template = metadata.template !;
      const templateMeta = this._directiveNormalizer.normalizeTemplate({
        ngModuleType,
        componentType: directiveType,
        moduleUrl: this._reflector.componentModuleUrl(directiveType, annotation),
        encapsulation: template.encapsulation,
        template: template.template,
        templateUrl: template.templateUrl,
        styles: template.styles,
        styleUrls: template.styleUrls,
        animations: template.animations,
        interpolation: template.interpolation,
        preserveWhitespaces: template.preserveWhitespaces
      });
      if (isPromise(templateMeta) && isSync) {
        this._reportError(componentStillLoadingError(directiveType), directiveType);
        return null;
      }
      // 并將元數(shù)據(jù)進行存儲
      return SyncAsync.then(templateMeta, createDirectiveMetadata);
    } else {
      // 指令,直接存儲元數(shù)據(jù)
      createDirectiveMetadata(null);
      return null;
    }
  }
  // 獲取給定指令(組件)的元數(shù)據(jù)信息
  getDirectiveMetadata(directiveType: any): cpl.CompileDirectiveMetadata {
    const dirMeta = this._directiveCache.get(directiveType)!;
    ...
    return dirMeta;
  }
  // 獲取給定指令(組件)的元數(shù)據(jù)摘要信息
  getDirectiveSummary(dirType: any): cpl.CompileDirectiveSummary {
    const dirSummary =
        <cpl.CompileDirectiveSummary>this._loadSummary(dirType, cpl.CompileSummaryKind.Directive);
    ...
    return dirSummary;
  }
}

可以看到,在編譯過程中,不管是組件、指令、管道,還是模塊,這些類在編譯過程中的元數(shù)據(jù),都使用Map來存儲。

總結(jié)

本節(jié)我們介紹了 Angular 中的裝飾器和元數(shù)據(jù),其中元數(shù)據(jù)用于描述類的定義和行為。

在 Angular 編譯過程中,會使用Map的數(shù)據(jù)結(jié)構(gòu)來維護和存儲裝飾器的元數(shù)據(jù),并根據(jù)這些元數(shù)據(jù)信息來編譯組件、指令、管道和模塊等。

更多編程相關(guān)知識,請訪問:編程教學(xué)?。?/p>

以上是聊聊Angular中的元資料(Metadata)和裝飾器(Decorator)的詳細內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72
利用紐約時報API進行元資料爬取 利用紐約時報API進行元資料爬取 Sep 02, 2023 pm 10:13 PM

簡介上週,我寫了一篇關(guān)於抓取網(wǎng)頁以收集元資料的介紹,並提到不可能抓取《紐約時報》網(wǎng)站。 《紐約時報》付費牆會阻止您收集基本元資料的嘗試。但有一種方法可以使用紐約時報API來解決這個問題。最近我開始在Yii平臺上建立一個社群網(wǎng)站,我將在以後的教程中發(fā)布該網(wǎng)站。我希望能夠輕鬆添加與網(wǎng)站內(nèi)容相關(guān)的連結(jié)。雖然人們可以輕鬆地將URL貼到表單中,但提供標題和來源資訊卻非常耗時。因此,在今天的教程中,我將擴展我最近編寫的抓取程式碼,以在添加《紐約時報》連結(jié)時利用《紐約時報》API來收集頭條新聞。請記住,我參與了

如何在Ubuntu 24.04上安裝Angular 如何在Ubuntu 24.04上安裝Angular Mar 23, 2024 pm 12:20 PM

Angular.js是一種可自由存取的JavaScript平臺,用於建立動態(tài)應(yīng)用程式。它允許您透過擴展HTML的語法作為模板語言,以快速、清晰地表示應(yīng)用程式的各個方面。 Angular.js提供了一系列工具,可協(xié)助您編寫、更新和測試程式碼。此外,它還提供了許多功能,如路由和表單管理。本指南將討論在Ubuntu24上安裝Angular的方法。首先,您需要安裝Node.js。 Node.js是一個基於ChromeV8引擎的JavaScript運行環(huán)境,可讓您在伺服器端執(zhí)行JavaScript程式碼。要在Ub

淺析angular中怎麼使用monaco-editor 淺析angular中怎麼使用monaco-editor Oct 17, 2022 pm 08:04 PM

angular中怎麼使用monaco-editor?以下這篇文章記錄下最近的一次業(yè)務(wù)中用到的 m??onaco-editor 在 angular 中的使用,希望對大家有幫助!

如何使用PHP和Angular進行前端開發(fā) 如何使用PHP和Angular進行前端開發(fā) May 11, 2023 pm 04:04 PM

隨著網(wǎng)路的快速發(fā)展,前端開發(fā)技術(shù)也不斷改進與迭代。 PHP和Angular是兩種廣泛應(yīng)用於前端開發(fā)的技術(shù)。 PHP是一種伺服器端腳本語言,可以處理表單、產(chǎn)生動態(tài)頁面和管理存取權(quán)限等任務(wù)。而Angular是一種JavaScript的框架,可以用來開發(fā)單一頁面應(yīng)用程式和建構(gòu)元件化的網(wǎng)頁應(yīng)用程式。本篇文章將介紹如何使用PHP和Angular進行前端開發(fā),以及如何將它們

一文探究Angular中的服務(wù)端渲染(SSR) 一文探究Angular中的服務(wù)端渲染(SSR) Dec 27, 2022 pm 07:24 PM

你知道 Angular Universal 嗎?可以幫助網(wǎng)站提供更好的 SEO 支援哦!

使用Python存取各種音訊和視訊檔案的元數(shù)據(jù) 使用Python存取各種音訊和視訊檔案的元數(shù)據(jù) Sep 05, 2023 am 11:41 AM

我們可以使用Mutagen和Python中的eyeD3模組存取音訊檔案的元資料。對於視訊元數(shù)據(jù),我們可以使用影片和Python中的OpenCV庫。元資料是提供有關(guān)其他資料(例如音訊和視訊資料)的資訊的資料。音訊和視訊檔案的元資料包括檔案格式、檔案解析度、檔案大小、持續(xù)時間、位元率等。透過存取這些元數(shù)據(jù),我們可以更有效地管理媒體並分析元數(shù)據(jù)以獲得一些有用的信息。在本文中,我們將了解Python提供的一些用於存取音訊和視訊檔案元資料的庫或模組。存取音頻元資料一些用於存取音訊檔案元資料的庫是-使用誘變

使用Angular和Node進行基於令牌的身份驗證 使用Angular和Node進行基於令牌的身份驗證 Sep 01, 2023 pm 02:01 PM

身份驗證是任何網(wǎng)路應(yīng)用程式中最重要的部分之一。本教程討論基於令牌的身份驗證系統(tǒng)以及它們與傳統(tǒng)登入系統(tǒng)的差異。在本教程結(jié)束時,您將看到一個用Angular和Node.js編寫的完整工作演示。傳統(tǒng)身份驗證系統(tǒng)在繼續(xù)基於令牌的身份驗證系統(tǒng)之前,讓我們先來看看傳統(tǒng)的身份驗證系統(tǒng)。使用者在登入表單中提供使用者名稱和密碼,然後點擊登入。發(fā)出請求後,透過查詢資料庫在後端驗證使用者。如果請求有效,則使用從資料庫中獲取的使用者資訊建立會話,然後在回應(yīng)頭中傳回會話訊息,以便將會話ID儲存在瀏覽器中。提供用於存取應(yīng)用程式中受

Angular元件及其顯示屬性:了解非block預(yù)設(shè)值 Angular元件及其顯示屬性:了解非block預(yù)設(shè)值 Mar 15, 2024 pm 04:51 PM

Angular框架中元件的預(yù)設(shè)顯示行為不是區(qū)塊級元素。這種設(shè)計選擇促進了元件樣式的封裝,並鼓勵開發(fā)人員有意識地定義每個元件的顯示方式。透過明確設(shè)定CSS屬性 display,Angular組件的顯示可以完全控制,從而實現(xiàn)所需的佈局和響應(yīng)能力。

See all articles