目錄
provider的應用場景下面,我們透過實際例子,來對幾個提供者的使用場景進行說明。
emm...你是否覺得上述的寫法過於複雜了,而在實際開發中,我們大多數的場景是無需手動建立的
useValue 值提供商
useExisting 别名提供商
ModuleInjector 和 ElementInjector 层级注入器的意义
ModuleInjector 模块注入器
ElementInjector 组件注入器
@Optional()、@Self()、@SkipSelf()、@Host() 修饰符的使用
@Optional()
@Self()
@SkipSelf()
@Host()
multi 多服务提供商
参考链接
首頁 web前端 js教程 深入淺析Angular怎麼使用依賴注入

深入淺析Angular怎麼使用依賴注入

Sep 29, 2021 am 11:23 AM
angular 依賴注入

這篇文章為大家介紹一下依賴注入在 Angular 中的應用,希望對大家有幫助!

深入淺析Angular怎麼使用依賴注入

本文透過實際案例,帶大家了解依賴注入Angular中的應用與部分實作原理,其中包含

  • useFactoryuseClassuseValueuseExisting 不同提供者的應用程式場景

  • ModuleInjectorElementInjector不同層次注入器的意義

  • ##@Injectable() @NgModule()中定義provider的差異

  • ##@Optional()

    @Self()@SkipSelf()@Host() 修飾符的使用

  • muti

    (多提供者)的應用場景

  • 【相關教學推薦:《
angular教學

》】如果你還不清楚什麼是

依賴注入

,可以先看這篇文章詳解依賴注入

useFactory、useClass、useValue 和useExisting 不同型別

provider的應用場景下面,我們透過實際例子,來對幾個提供者的使用場景進行說明。

useFactory 工廠提供者

某天,咱們接到一個需求:實作一個

本地儲存

的功能,並將其注入Angular應用程式中,使其可以在系統中全域使用首先編寫服務類別

storage.service.ts

,實作其儲存功能<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>// storage.service.ts export class StorageService { get(key: string) { return JSON.parse(localStorage.getItem(key) || &amp;#39;{}&amp;#39;) || {}; } set(key: string, value: ITokenModel | null): boolean { localStorage.setItem(key, JSON.stringify(value)); return true; } remove(key: string) { localStorage.removeItem(key); } }</pre><div class="contentsignin">登入後複製</div></div>如果你馬上在

user.component.ts

中嘗試使用<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>// user.component.ts @Component({ selector: &amp;#39;app-user&amp;#39;, templateUrl: &amp;#39;./user.component.html&amp;#39;, styleUrls: [&amp;#39;./user.component.css&amp;#39;] }) export class CourseCardComponent { constructor(private storageService: StorageService) { ... } ... }</pre><div class="contentsignin">登入後複製</div></div>你應該會看到這樣的一個錯誤:

NullInjectorError: No provider for StorageService!
登入後複製

顯而易見,我們並沒有將

StorageService

加入到Angular的依賴注入系統Angular無法取得StorageService依賴項的Provider,也就無法實例化這個類,更沒法呼叫類別中的方法。 接下來,我們本著缺撒補撒的理念,手動添加一個

Provider

。修改storage.service.ts檔案如下<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>// storage.service.ts export class StorageService { get(key: string) { return JSON.parse(localStorage.getItem(key) || &amp;#39;{}&amp;#39;) || {}; } set(key: string, value: any) { localStorage.setItem(key, JSON.stringify(value)); } remove(key: string) { localStorage.removeItem(key); } } // 添加工厂函数,实例化StorageService export storageServiceProviderFactory(): StorageService { return new StorageService(); }</pre><div class="contentsignin">登入後複製</div></div>透過上述程式碼,我們已經有了

Provider

。那麼接下來的問題,就是如果讓Angular每次掃描到StorageService這個依賴項的時候,讓其去執行storageServiceProviderFactory方法,來建立實例這就引出來了下一個知識點

InjectionToken

在一個服務類別中,我們常常需要加入多個依賴項,來確保服務的可用。而

InjectionToken

是各個依賴項的唯一標識,它讓Angular的依賴注入系統能準確的找到各個依賴項的Provider接下來,我們手動新增一個

InjectionToken

<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>// storage.service.ts import { InjectionToken } from &amp;#39;@angular/core&amp;#39;; export class StorageService { get(key: string) { return JSON.parse(localStorage.getItem(key) || &amp;#39;{}&amp;#39;) || {}; } set(key: string, value: any) { localStorage.setItem(key, JSON.stringify(value)); } remove(key: string) { localStorage.removeItem(key); } } export storageServiceProviderFactory(): StorageService { return new StorageService(); } // 添加StorageServiced的InjectionToken export const STORAGE_SERVICE_TOKEN = new InjectionToken&lt;StorageService&gt;(&amp;#39;AUTH_STORE_TOKEN&amp;#39;);</pre><div class="contentsignin">登入後複製</div></div>ok,我們已經有了

StorageService

ProviderInjectionToken接下來,我們需要一個配置,讓

Angular

依賴注入系統能夠對其進行識別,在掃描到StorageService(Dependency )的時候,根據STORAGE_SERVICE_TOKEN(InjectionToken)去找到對應的storageServiceProviderFactory(Provider),然後建立這個依賴項的實例。如下,我們在module中的@NgModule()裝飾器中進行配置:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>// user.module.ts @NgModule({ imports: [ ... ], declarations: [ ... ], providers: [ { provide: STORAGE_SERVICE_TOKEN, // 与依赖项关联的InjectionToken,用于控制工厂函数的调用 useFactory: storageServiceProviderFactory, // 当需要创建并注入依赖项时,调用该工厂函数 deps: [] // 如果StorageService还有其他依赖项,这里添加 } ] }) export class UserModule { }</pre><div class="contentsignin">登入後複製</div></div>到這裡,我們完成了

依賴

#的實現。最後,還需要讓Angular知道在哪裡注入Angular提供了@Inject裝飾器來識別<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>// user.component.ts @Component({ selector: &amp;#39;app-user&amp;#39;, templateUrl: &amp;#39;./user.component.html&amp;#39;, styleUrls: [&amp;#39;./user.component.css&amp;#39;] }) export class CourseCardComponent { constructor(@Inject(STORAGE_SERVICE_TOKEN) private storageService: StorageService) { ... } ... }</pre><div class="contentsignin">登入後複製</div></div>到此,我們便可以在

user.component.ts

呼叫# StorageService裡面的方法了

useClass 類別提供者

emm...你是否覺得上述的寫法過於複雜了,而在實際開發中,我們大多數的場景是無需手動建立的

Provider

InjectionToken。如下:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>// user.component.ts @Component({ selector: &amp;#39;app-user&amp;#39;, templateUrl: &amp;#39;./user.component.html&amp;#39;, styleUrls: [&amp;#39;./user.component.css&amp;#39;] }) export class CourseCardComponent { constructor(private storageService: StorageService) { ... } ... } // storage.service.ts @Injectable({ providedIn: &#39;root&#39; }) export class StorageService {} // user.module.ts @NgModule({ imports: [ ... ], declarations: [ ... ], providers: [StorageService] }) export class UserModule { }</pre><div class="contentsignin">登入後複製</div></div>下面,我們來對上述的這種

簡寫模式

進行剖析。

user.component.ts

,我們捨棄了@Inject裝飾器,直接加入依賴項private storageService: StorageService,這得益於AngularInjectionToken的設計。 <blockquote><p><code>InjectionToken不一定必须是一个InjectionToken object,只要保证它在运行时环境中能够识别对应的唯一依赖项即可。所以,在这里,你可以用类名即运行时中的构造函数名称来作为依赖项InjectionToken。省略创建InjectionToken这一步骤。

// user.module.ts
@NgModule({
  imports: [
    ...
  ],
  declarations: [
    ...
  ],
  providers: [{
    provide: StorageService, // 使用构造函数名作为InjectionToken
    useFactory: storageServiceProviderFactory,
    deps: []
  }]
})
export class UserModule { }
登入後複製

注意:由于Angular依赖注入系统是在运行时环境中根据InjectionToken识别依赖项,进行依赖注入的。所以这里不能使用interface名称作为InjectionToken,因为其只存在于Typescript语言的编译期,并不存在于运行时中。而对于类名来说,其在运行时环境中以构造函数名体现,可以使用。

接下来,我们可以使用useClass替换useFactory,其实也能达到创建实例的效果,如下:

...
providers: [{
  provide: StorageService,
  useClass: StorageService,
  deps: []
}]
...
登入後複製

当使用useClass时,Angular会将后面的值当作一个构造函数,在运行时环境中,直接执行new指令进行实例化,这也无需我们再手动创建 Provider

当然,基于Angular依赖注入设计,我们可以写得更简单

...
providers: [StorageService]
...
登入後複製

直接写入类名providers数组中,Angular会识别其是一个构造函数,然后检查函数内部,创建一个工厂函数去查找其构造函数中的依赖项,最后再实例化

useClass还有一个特性是,Angular会根据依赖项Typescript中的类型定义,作为其运行时InjectionToken去自动查找Provider。所以,我们也无需使用@Inject装饰器来告诉Angular在哪里注入了

你可以简写如下

  ...
  // 无需手动注入 :constructor(@Inject(StorageService) private storageService: StorageService)
  constructor(private storageService: StorageService) {
    ...
  }
  ...
登入後複製

这也就是我们平常开发中,最常见的一种写法。

useValue 值提供商

完成本地存储服务的实现后,我们又收到了一个新需求,研发老大希望提供一个配置文件,来存储StorageService的一些默认行为

我们先创建一个配置

const storageConfig = {
  suffix: &#39;app_&#39; // 添加一个存储key的前缀
  expires: 24 * 3600 * 100 // 过期时间,毫秒戳
}
登入後複製

useValue则可以 cover 住这种场景。其可以是一个普通变量,也可以是一个对象形式。

配置方法如下:

// config.ts
export interface STORAGE_CONFIG = {
  suffix: string;
  expires: number;
}

export const STORAGE_CONFIG_TOKEN = new InjectionToken('storage-config');
export const storageConfig = {
  suffix: &#39;app_&#39; // 添加一个存储key的前缀
  expires: 24 * 3600 * 100 // 过期时间,毫秒戳
}

// user.module.ts
@NgModule({
  ...
  providers: [
    StorageService,
    {
      provide: STORAGE_CONFIG_TOKEN,
      useValue: storageConfig
    }
  ],
  ...
})
export class UserModule {}
登入後複製

user.component.ts组件中,直接使用配置对象

// user.component.ts
@Component({
  selector: &#39;app-user&#39;,
  templateUrl: &#39;./user.component.html&#39;,
  styleUrls: [&#39;./user.component.css&#39;]
})
export class CourseCardComponent  {
  constructor(private storageService: StorageService, @Inject(STORAGE_CONFIG_TOKEN) private storageConfig: StorageConfig) {
    ...
  }

  getKey(): void {
    const { suffix } = this.storageConfig;
    console.log(this.storageService.get(suffix + &#39;demo&#39;));
  }
}
登入後複製

useExisting 别名提供商

如果我们需要基于一个已存在的provider来创建一个新的provider,或需要重命名一个已存在的provider时,可以用useExisting属性来处理。比如:创建一个angular的表单控件,其在一个表单中会存在多个,每个表单控件存储不同的值。我们可以基于已有的表单控件provider来创建

// new-input.component.ts
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from &#39;@angular/forms&#39;;

@Component({
  selector: &#39;new-input&#39;,
  exportAs: &#39;newInput&#39;,
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => NewInputComponent), // 这里的NewInputComponent已经声明了,但还没有被定义。无法直接使用,使用forwardRef可以创建一个间接引用,Angular在后续在解析该引用
      multi: true
    }
  ]
})
export class NewInputComponent implements ControlValueAccessor {
  ...
}
登入後複製

ModuleInjector 和 ElementInjector 层级注入器的意义

Angular中有两个注入器层次结构

  • ModuleInjector —— 使用 @NgModule() 或 @Injectable() 的方式在模块中注入

  • ElementInjector —— 在 @Directive() 或 @Component() 的 providers 属性中进行配置

我们通过一个实际例子来解释两种注入器的应用场景,比如:设计一个展示用户信息的卡片组件

ModuleInjector 模块注入器

我们使用user-card.component.ts来显示组件,用UserService来存取该用户的信息

// user-card.component.ts
@Component({
  selector: &#39;user-card.component.ts&#39;,
  templateUrl: &#39;./user-card.component.html&#39;,
  styleUrls: [&#39;./user-card.component.less&#39;]
})
export class UserCardComponent {
  ...
}

// user.service.ts
@Injectable({
  providedIn: "root"
})
export class UserService {
  ...
}
登入後複製
登入後複製

上述代码是通过@Injectable添加到根模块中,root即根模块的别名。其等价于下面的代码

// user.service.ts
export class UserService {
  ...
}

// app.module.ts
@NgModule({
  ...
  providers: [UserService], // 通过providers添加
})
export class AppModule {}
登入後複製

当然,如果你觉得UserService只会在UserModule模块下使用的话,你大可不必将其添加到根模块中,添加到所在模块即可

// user.service.ts
@Injectable({
  providedIn: UserModule
})
export class UserService {
  ...
}
登入後複製

如果你足够细心,会发现上述例子中,我们既可以通过在当前service文件中的@Injectable({ provideIn: xxx })定义provider,也可以在其所属module中的@NgModule({ providers: [xxx] })定义。那么,他们有什么区别呢?

@Injectable()@NgModule()除了使用方式不同外,还有一个很大的区别是:

使用 @Injectable() 的 providedIn 属性优于 @NgModule() 的 providers 数组,因为使用 @Injectable() 的 providedIn 时,优化工具可以进行摇树优化 Tree Shaking,从而删除你的应用程序中未使用的服务,以减小捆绑包尺寸。

我们通过一个例子来解释上面的概述。随着业务的增长,我们扩展了UserService1UserService2两个服务,但由于某些原因,UserService2一直未被使用。

如果通过@NgModule()providers引入依赖项,我们需要在user.module.ts文件中引入对应的user1.service.tsuser2.service.ts文件,然后在providers数组中添加UserService1UserService2引用。而由于UserService2所在文件在module文件中被引用,导致Angular中的tree shaker错误的认为这个UserService2已经被使用了。无法进行摇树优化。代码示例如下:

// user.module.ts
import UserService1 from &#39;./user1.service.ts&#39;;
import UserService2 from &#39;./user2.service.ts&#39;;
@NgModule({
  ...
  providers: [UserService1, UserService2], // 通过providers添加
})
export class UserModule {}
登入後複製

那么,如果通过@Injectable({providedIn: UserModule})这种方式,我们实际是在服务类自身文件中引用了use.module.ts,并为其定义了一个provider。无需在UserModule中在重复定义,也就不需要在引入user2.service.ts文件了。所以,当UserService2没有被依赖时,即可被优化掉。代码示例如下:

// user2.service.ts
import UserModule from &#39;./user.module.ts&#39;;
@Injectable({
  providedIn: UserModule
})
export class UserService2 {
  ...
}
登入後複製

ElementInjector 组件注入器

在了解完ModuleInjector后,我们继续通过刚才的例子讲述ElementInjector

最初,我们系统中的用户只有一个,我们也只需要一个组件和一个UserService来存取这个用户的信息即可

// user-card.component.ts
@Component({
  selector: &#39;user-card.component.ts&#39;,
  templateUrl: &#39;./user-card.component.html&#39;,
  styleUrls: [&#39;./user-card.component.less&#39;]
})
export class UserCardComponent {
  ...
}

// user.service.ts
@Injectable({
  providedIn: "root"
})
export class UserService {
  ...
}
登入後複製
登入後複製

注意:上述代码将UserService被添加到根模块中,它仅会被实例化一次。

如果这时候系统中有多个用户,每个用户卡片组件里的UserService需存取对应用户的信息。如果还是按照上述的方法,UserService只会生成一个实例。那么就可能出现,张三存了数据后,李四去取数据,取到的是张三的结果。

那么,我们有办法实例化多个UserService,让每个用户的数据存取操作隔离开么?

答案是有的。我们需要在user.component.ts文件中使用ElementInjector,将UserServiceprovider添加即可。如下:

// user-card.component.ts
@Component({
  selector: &#39;user-card.component.ts&#39;,
  templateUrl: &#39;./user-card.component.html&#39;,
  styleUrls: [&#39;./user-card.component.less&#39;],
  providers: [UserService]
})
export class UserCardComponent {
  ...
}
登入後複製

通过上述代码,每个用户卡片组件都会实例化一个UserService,来存取各自的用户信息。

如果要解释上述的现象,就需要说到AngularComponents and Module Hierarchical Dependency Injection

在组件中使用依赖项时,Angular会优先在该组件的providers中寻找,判断该依赖项是否有匹配的provider。如果有,则直接实例化。如果没有,则查找父组件的providers,如果还是没有,则继续找父级的父级,直到根组件(app.component.ts)。如果在根组件中找到了匹配的provider,会先判断其是否有存在的实例,如果有,则直接返回该实例。如果没有,则执行实例化操作。如果根组件仍未找到,则开始从原组件所在的module开始查找,如果原组件所在module不存在,则继续查找父级module,直到根模块(app.module.ts)。最后,仍未找到则报错No provider for xxx

@Optional()、@Self()、@SkipSelf()、@Host() 修饰符的使用

Angular应用中,当依赖项寻找provider时,我们可以通过一些修饰符来对搜索结果进行容错处理限制搜索的范围

@Optional()

通过@Optional()装饰服务,表明让该服务可选。即如果在程序中,没有找到服务匹配的provider,也不会程序崩溃,报错No provider for xxx,而是返回null

export class UserCardComponent {
  constructor(@Optional private userService: UserService) {}
}
登入後複製

@Self()

使用@Self()Angular仅查看当前组件或指令的ElementInjector

如下,Angular只会在当前UserCardComponentproviders中搜索匹配的provider,如果未匹配,则直接报错。No provider for UserService

// user-card.component.ts
@Component({
  selector: &#39;user-card.component.ts&#39;,
  templateUrl: &#39;./user-card.component.html&#39;,
  styleUrls: [&#39;./user-card.component.less&#39;],
  providers: [UserService],
})
export class UserCardComponent {
  constructor(@Self() private userService?: UserService) {}
}
登入後複製

@SkipSelf()

@SkipSelf()@Self()相反。使用@SkipSelf()Angular在父ElementInjector中而不是当前ElementInjector中开始搜索服务.

// 子组件 user-card.component.ts
@Component({
  selector: &#39;user-card.component.ts&#39;,
  templateUrl: &#39;./user-card.component.html&#39;,
  styleUrls: [&#39;./user-card.component.less&#39;],
  providers: [UserService], // not work
})
export class UserCardComponent {
  constructor(@SkipSelf() private userService?: UserService) {}
}

// 父组件 parent-card.component.ts
@Component({
  selector: &#39;parent-card.component.ts&#39;,
  templateUrl: &#39;./parent-card.component.html&#39;,
  styleUrls: [&#39;./parent-card.component.less&#39;],
  providers: [
    {
      provide: UserService,
      useClass: ParentUserService, // work
    },
  ],
})
export class ParentCardComponent {
  constructor() {}
}
登入後複製

@Host()

@Host()使你可以在搜索provider时将当前组件指定为注入器树的最后一站。这和@Self()类似,即使树的更上级有一个服务实例,Angular也不会继续寻找。

multi 多服务提供商

某些场景下,我们需要一个InjectionToken初始化多个provider。比如:在使用拦截器的时候,我们希望在default.interceptor.ts之前添加一个 用于 token 校验的JWTInterceptor

...
const NET_PROVIDES = [
  { provide: HTTP_INTERCEPTORS, useClass: DefaultInterceptor, multi: true },
  { provide: HTTP_INTERCEPTORS, useClass: JWTInterceptor, multi: true }
];
...
登入後複製

multi: 为false时,provider的值会被覆盖;设置为true,将生成多个provider并与唯一InjectionToken HTTP_INTERCEPTORS关联。最后可以通过HTTP_INTERCEPTORS获取所有provider的值

参考链接

Angular Dependency Injection: Complete Guide

Angular 中的依赖注入

更多编程相关知识,请访问:编程教学!!

以上是深入淺析Angular怎麼使用依賴注入的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

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整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

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

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

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

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

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

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

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

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

淺析Angular中的獨立組件,看看怎麼使用 淺析Angular中的獨立組件,看看怎麼使用 Jun 23, 2022 pm 03:49 PM

這篇文章帶大家了解Angular中的獨立元件,看看怎麼在Angular中建立一個獨立元件,怎麼在獨立元件中導入已有的模組,希望對大家有幫助!

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

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

專案過大怎麼辦?如何合理拆分Angular項目? 專案過大怎麼辦?如何合理拆分Angular項目? Jul 26, 2022 pm 07:18 PM

Angular專案過大,怎麼合理拆分它?以下這篇文章跟大家介紹一下合理分割Angular專案的方法,希望對大家有幫助!

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

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

See all articles