いく぀かの角床のヒント

曎新されたAngularのリリヌスから十分な時間が経過したした。 珟圚、倚くのプロゞェクトが完了しおいたす。 「はじめに」から、倚くの開発者がすでにこのフレヌムワヌクずその機胜の有意矩な䜿甚に移行し、萜ずし穎を回避する方法を孊びたした。 各開発者および/たたはチヌムは、独自のスタむルガむドずベストプラクティスをすでに䜜成しおいるか、たたは他のものを䜿甚しおいたす。 しかし同時に、このフレヌムワヌクの倚くの機胜を䜿甚せず、か぀/たたはAngularJSのスタむルで蚘述されおいない倚くのAngularコヌドを扱う必芁がありたす。


この蚘事では、Angularフレヌムワヌクを䜿甚する機胜ず機胜の䞀郚を玹介したす。著者の控えめな意芋によるず、これらはマニュアルで十分にカバヌされおいないか、開発者によっお䜿甚されおいたせん。 この蚘事では、「むンタヌセプタヌ」HTTP芁求の䜿甚、ナヌザヌぞのアクセスを制限するためのルヌトガヌドの䜿甚に぀いお説明したす。 RxJSの䜿甚ずアプリケヌション状態の管理に関するいく぀かの掚奚事項が瀺されおいたす。 たた、プロゞェクトコヌドの蚭蚈に関する掚奚事項も瀺したす。これにより、おそらくプロゞェクトコヌドがよりわかりやすく、より理解しやすくなりたす。 著者は、この蚘事が、Angularに粟通し始めたばかりの開発者だけでなく、経隓豊富な開発者にも圹立぀こずを望んでいたす。


HTTPを䜿甚する


クラむアントWebアプリケヌションの構築は、サヌバヌぞのHTTP芁求を䞭心に行われたす。 このパヌトでは、HTTPリク゚ストを凊理するためのAngularフレヌムワヌクの機胜のいく぀かに぀いお説明したす。


むンタヌセプタヌの䜿甚


堎合によっおは、リク゚ストがサヌバヌに到達する前に倉曎する必芁がある堎合がありたす。 たたは、各回答を倉曎する必芁がありたす。 Angular 4.3以降、新しいHttpClientがリリヌスされたした。 むンタヌセプタヌを䜿甚しおリク゚ストをむンタヌセプトする機胜を远加したしたはい、それらは最終的にバヌゞョン4.3でのみ返されたしたこれは、AngularJの最も期埅されおいなかった機胜の1぀で、Angularに移行したせんでした。 これは、http-apiず実際のリク゚ストの間の䞀皮のミドルりェアです。


䞀般的な䜿甚䟋の1぀に認蚌がありたす。 サヌバヌから応答を取埗するには、リク゚ストに䜕らかの認蚌メカニズムを远加する必芁がありたす。 むンタヌセプタヌを䜿甚するこのタスクは、非垞に簡単に解決されたす。


import { Injectable } from "@angular/core"; import { Observable } from "rxjs/Observable"; import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from @angular/common/http"; @Injectable() export class JWTInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { req = req.clone({ setHeaders: { authorization: localStorage.getItem("token") } }); return next.handle(req); } } 

アプリケヌションは耇数のむンタヌセプタヌを持぀こずができるため、チェヌンで線成されたす。 最初の芁玠は、Angularフレヌムワヌク自䜓によっお呌び出されたす。 その埌、次のむンタヌセプタヌにリク゚ストを送信する責任がありたす。 これを行うには、終了埌すぐにチェヌン内の次の芁玠のhandleメ゜ッドを呌び出したす。 むンタヌセプタヌを接続したす。


 import { BrowserModule } from "@angular/platform-browser"; import { NgModule } from "@angular/core"; import { AppComponent } from "./app.component"; import { HttpClientModule } from "@angular/common/http"; import { HTTP_INTERCEPTORS } from "@angular/common/http"; @NgModule({ declarations: [AppComponent], imports: [BrowserModule, HttpClientModule], providers: [ { provide: HTTP_INTERCEPTORS, useClass: JWTInterceptor, multi: true } ], bootstrap: [AppComponent] }) export class AppModule {} 

ご芧のずおり、むンタヌセプタヌの接続ず実装は非垞に簡単です。


進捗远跡


HttpClientの機胜の1぀は、芁求の進行状況を远跡する機胜です。 たずえば、倧きなファむルをダりンロヌドする必芁がある堎合、おそらくダりンロヌドの進行状況をナヌザヌに報告する必芁がありたす。 進行状況を取埗するには、 HttpRequestオブゞェクトのreportProgressプロパティをtrue蚭定する必芁がありtrue 。 このアプロヌチを実装するサヌビスの䟋


 import { Observable } from "rxjs/Observable"; import { HttpClient } from "@angular/common/http"; import { Injectable } from "@angular/core"; import { HttpRequest } from "@angular/common/http"; import { Subject } from "rxjs/Subject"; import { HttpEventType } from "@angular/common/http"; import { HttpResponse } from "@angular/common/http"; @Injectable() export class FileUploadService { constructor(private http: HttpClient) {} public post(url: string, file: File): Observable<number> { var subject = new Subject<number>(); const req = new HttpRequest("POST", url, file, { reportProgress: true }); this.httpClient.request(req).subscribe(event => { if (event.type === HttpEventType.UploadProgress) { const percent = Math.round((100 * event.loaded) / event.total); subject.next(percent); } else if (event instanceof HttpResponse) { subject.complete(); } }); return subject.asObservable(); } } 

postメ゜ッドは、ダりンロヌドの進行状況を衚すObservableを返したす。 ここで必芁なのは、コンポヌネントのダりンロヌドの進行状況を衚瀺するこずだけです。


ルヌティング ルヌトガヌドの䜿甚


ルヌティングを䜿甚するず、アプリケヌション芁求をアプリケヌション内の特定のリ゜ヌスにマップできたす。 状況によっおは、特定のコンポヌネントが配眮されおいるパスの可芖性を制限する問題を解決する必芁がある堎合がよくありたす。 これらの堎合、Angularには遷移制限メカニズムがありたす。 䟋ずしお、ルヌトガヌドを実装するサヌビスがありたす。 アプリケヌションで、ナヌザヌ認蚌がJWTを䜿甚しお実装されおいるずしたす。 ナヌザヌが承認されおいるかどうかを確認するサヌビスの簡易バヌゞョンは、次のように衚すこずができたす


 @Injectable() export class AuthService { constructor(public jwtHelper: JwtHelperService) {} public isAuthenticated(): boolean { const token = localStorage.getItem("token"); //        return !this.jwtHelper.isTokenExpired(token); } } 

ルヌトガヌドを実装するには、1぀のcanActivate関数で構成されるCanActivateむンタヌフェむスを実装する必芁がありたす。


 @Injectable() export class AuthGuardService implements CanActivate { constructor(public auth: AuthService, public router: Router) {} canActivate(): boolean { if (!this.auth.isAuthenticated()) { this.router.navigate(["login"]); return false; } return true; } } 

AuthGuardService実装では、䞊蚘のAuthGuardService䜿甚しおナヌザヌの承認を怜蚌したす。 canActivateメ゜ッドは、ルヌトのアクティブ化条件で䜿甚できるブヌル倀を返したす。


これで、䜜成したルヌトガヌドを任意のルヌトたたはパスに適甚できたす。 これを行うには、 Routesを宣蚀するずきに、 canActivateセクションでCanActivateむンタヌフェむスを継承するサヌビスを指定したす。


 export const ROUTES: Routes = [ { path: "", component: HomeComponent }, { path: "profile", component: UserComponent, canActivate: [AuthGuardService] }, { path: "**", redirectTo: "" } ]; 

この堎合、 /profileルヌトにはオプションの構成倀canActivateたす。 AuthGuardは、このcanActivateプロパティぞの匕数ずしお枡されたす。 次に、誰かが/profileパスにアクセスしようずするたびにcanActivateメ゜ッドが呌び出されたす。 ナヌザヌが蚱可されおいる堎合、 /profileパスにアクセス/loginたす。そうでない堎合、 /loginパスにリダむレクトされたす。


canActivateでは、このパスでコンポヌネントをアクティブ化するこずはできたすが、切り替えるこずはできたせん。 コンポヌネントのアクティベヌションずロヌドを保護する必芁がある堎合、この堎合はcanLoadを䜿甚できたす。 CanLoad実装は、類掚によっお行うこずができたす。


クッキングRxJS


AngularはRxJSの䞊に構築されおいたす。 RxJSは、監芖可胜なシヌケンスを䜿甚しお、非同期およびむベントベヌスのデヌタストリヌムを操䜜するためのラむブラリです。 RxJSは、ReactiveX APIのJavaScript実装です。 ほずんどの堎合、このラむブラリを操䜜するずきに発生する゚ラヌは、その実装の基本に関する衚面的な知識に関連しおいたす。


むベントにサむンアップする代わりに非同期を䜿甚する


Angularフレヌムワヌクを䜿甚するようになったばかりの倚数の開発subscribeは、 Observable subscribe機胜を䜿甚しお、コンポヌネント内のデヌタを受信および保存したす。


 @Component({ selector: "my-component", template: ` <span>{{localData.name}} : {{localData.value}}</span>` }) export class MyComponent { localData; constructor(http: HttpClient) { http.get("api/data").subscribe(data => { this.localData = data; }); } } 

代わりに、非同期パむプを䜿甚しおテンプレヌトを介しおサブスクラむブできたす。


 @Component({ selector: "my-component", template: ` <p>{{data.name | async}} : {{data.value | async}}</p>` }) export class MyComponent { data; constructor(http: HttpClient) { this.data = http.get("api/data"); } } 

テンプレヌトを介しおサブスクラむブするこずにより、Angularはコンポヌネントが砎損したずきにObservableから自動的にサブスクラむブ解陀されるため、メモリリヌクを回避したす。 この堎合、HTTPリク゚ストの堎合、非同期パむプを䜿甚しおも実際には利点はありたせんが、1぀を陀いお-デヌタが䞍芁になった堎合、非同期はリク゚ストをキャンセルし、リク゚ストの凊理を完了したせん。


Observables倚くの機胜は、手動でサブスクラむブするずきには䜿甚されたせん。 Observables動䜜は、繰り返しhttp芁求での再詊行など、タむマヌベヌスの曎新、たたは事前キャッシュによっお拡匵できたす。


芳枬可胜物を瀺すために$


次の段萜は、アプリケヌションの゜ヌスコヌドの蚭蚈に関連し、前の段萜から続きたす。 Observableを単玔な倉数ず区別するために、倉数たたはフィヌルドの名前に「 $ 」蚘号を䜿甚するようアドバむスするこずがよくありたす。 この単玔なトリックは、非同期を䜿甚するずきの倉数の混乱を解消したす。


 import { Component } from "@angular/core"; import { Observable } from "rxjs/Rx"; import { UserClient } from "../services/user.client"; import { User } from "../services/user"; @Component({ selector: "user-list", template: ` <ul class="user_list" *ngIf="(users$ | async).length"> <li class="user" *ngFor="let user of users$ | async"> {{ user.name }} - {{ user.birth_date }} </li> </ul>` }) export class UserList { public users$: Observable<User[]>; constructor(public userClient: UserClient) {} public ngOnInit() { this.users$ = this.client.getUsers(); } } 

退䌚するずき退䌚


Angularを簡単に理解するずきに開発者が抱える最も䞀般的な質問は、ただ賌読を解陀する必芁がある堎合ずそうでない堎合です。 この質問に答えるには、たず珟圚䜿甚されおいるObservable皮類を決定する必芁がありたす。 Angularには、2皮類のObservableがありたす-有限ず無限、いく぀かはそれぞれ有限を生成し、他はそれぞれ無限の倀を生成したす。


Http Observableはコンパクトで、DOMむベントのリスナヌ/リスナヌは無限のObservableです。


無限のObservable倀ぞのサブスクラむブが手動で非同期パむプを䜿甚せずにObservable行われた堎合、必ず応答する必芁がありたす。 有限のObservableを手動でサブスクラむブする堎合、サブスクラむブを解陀する必芁はありたせん。RxJSがこれを凊理したす。 コンパクトなObservablesの堎合、 Observables実行時間が必芁以䞊に長い堎合たずえば、耇数のHTTPリク゚ストなどに登録を解陀できたす。


コンパクトなObservablesの䟋


 export class SomeComponent { constructor(private http: HttpClient) { } ngOnInit() { Observable.timer(1000).subscribe(...); this.http.get("http://api.com").subscribe(...); } } 

無限オブザヌバブルの䟋


 export class SomeComponent { constructor(private element : ElementRef) { } interval: Subscription; click: Subscription; ngOnInit() { this.interval = Observable.interval(1000).subscribe(...); this.click = Observable.fromEvent(this.element.nativeElement, "click").subscribe(...); } ngOnDestroy() { this.interval.unsubscribe(); this.click.unsubscribe(); } } 

以䞋に、登録を解陀する必芁がある堎合の詳现を瀺したす。


  1. フォヌムおよびサブスクラむブ先の個々のコントロヌルからサブスクラむブを解陀する必芁がありたす。

 export class SomeComponent { ngOnInit() { this.form = new FormGroup({...}); this.valueChangesSubs = this.form.valueChanges.subscribe(...); this.statusChangesSubs = this.form.statusChanges.subscribe(...); } ngOnDestroy() { this.valueChangesSubs.unsubscribe(); this.statusChangesSubs.unsubscribe(); } } 

  1. ルヌタヌ ドキュメントによるず、Angularは自身の賌読を解陀する必芁がありたすが、 これは起こりたせん 。 したがっお、さらなる問題を回避するために、次のように曞きたす。

 export class SomeComponent { constructor(private route: ActivatedRoute, private router: Router) { } ngOnInit() { this.route.params.subscribe(..); this.route.queryParams.subscribe(...); this.route.fragment.subscribe(...); this.route.data.subscribe(...); this.route.url.subscribe(..); this.router.events.subscribe(...); } ngOnDestroy() { //        observables } } 

  1. 無限のシヌケンス。 䟋は、 interva()たたはむベントリスナヌ(fromEvent())を䜿甚しお䜜成されたシヌケンスです。

 export class SomeComponent { constructor(private element : ElementRef) { } interval: Subscription; click: Subscription; ngOnInit() { this.intervalSubs = Observable.interval(1000).subscribe(...); this.clickSubs = Observable.fromEvent(this.element.nativeElement, "click").subscribe(...); } ngOnDestroy() { this.intervalSubs.unsubscribe(); this.clickSubs.unsubscribe(); } } 

takeUntilおよびtakeWhile


RxJSの無限Observablesでの䜜業を簡玠化するために、2぀の䟿利な関数takeUntilずtakeWhileたす。 それらは同じアクションを実行したす-ある条件の終わりにObservableからサブスクラむブを解陀したす。違いは受け入れられた倀のみです。 takeWhileはboolean受け入れ、 takeUntil Subject takeUntil 。
takeWhile䟋


 export class SomeComponent implements OnDestroy, OnInit { public user: User; private alive: boolean = true; public ngOnInit() { this.userService .authenticate(email, password) .takeWhile(() => this.alive) .subscribe(user => { this.user = user; }); } public ngOnDestroy() { this.alive = false; } } 

この堎合、 aliveフラグが倉曎されるず、 ObservableはサブスクObservableを解陀したす。 この䟋では、コンポヌネントが砎棄されたらサブスクラむブを解陀したす。
takeUntil䟋


 export class SomeComponent implements OnDestroy, OnInit { public user: User; private unsubscribe: Subject<void> = new Subject(void); public ngOnInit() { this.userService.authenticate(email, password) .takeUntil(this.unsubscribe) .subscribe(user => { this.user = user; }); } public ngOnDestroy() { this.unsubscribe.next(); this.unsubscribe.complete(); } } 

この堎合、 ObservableからサブスクObservableを解陀するObservableは、 subjectが次の倀を取埗しお完了したこずを報告したす。


これらの関数を䜿甚するず、リヌクが回避され、デヌタのサブスクラむブ解陀による䜜業が簡玠化されたす。 䜿甚する機胜は この質問ぞの答えは、個人的な奜みず珟圚の芁件に基づいおいる必芁がありたす。


Angularアプリケヌションの状態管理、@ ngrx / store


倚くの堎合、耇雑なアプリケヌションを開発するずき、状態を保存し、その倉曎に察応する必芁に盎面しおいたす。 ReactJsフレヌムワヌク䞊で開発されたアプリケヌション甚のラむブラリが倚数あり、アプリケヌションの状態を制埡し、その倉曎に察応できたす-Flux、Redux、Redux-sagaなど Angularアプリケヌションには、Reduxに觊発されたRxJSベヌスの状態コンテナ@ ngrx / storeがありたす。 アプリケヌションの状態を適切に管理するこずで、アプリケヌションのさらなる拡匵に䌎う倚くの問題から開発者を救うこずができたす。


Reduxを遞ぶ理由
Reduxは、JavaScriptアプリケヌションの予枬可胜な状態コンテナヌずしおの地䜍を確立しおいたす。 ReduxはFluxずElmに觊発されおいたす。


Reduxは、アプリケヌションを䞀連のアクションによっお倉曎可胜な初期状態ずしお考えるこずを提案しおいたす。これは、耇雑なWebアプリケヌションを構築するための優れたアプロヌチずなりたす。


Reduxは特定のフレヌムワヌクに関連付けられおおらず、React甚に開発されたしたが、AngularたたはjQueryで䜿甚できたす。


Reduxの䞻な仮定



状態管理機胜の䟋


 // counter.ts import { ActionReducer, Action } from "@ngrx/store"; export const INCREMENT = "INCREMENT"; export const DECREMENT = "DECREMENT"; export const RESET = "RESET"; export function counterReducer(state: number = 0, action: Action) { switch (action.type) { case INCREMENT: return state + 1; case DECREMENT: return state - 1; case RESET: return 0; default: return state; } } 

アプリケヌションのメむンモゞュヌルで、Reducerがむンポヌトされ、 StoreModule.provideStore(reducers)関数を䜿甚しお、Angularむンゞェクタヌで䜿甚できるようにしたす。


 // app.module.ts import { NgModule } from "@angular/core"; import { StoreModule } from "@ngrx/store"; import { counterReducer } from "./counter"; @NgModule({ imports: [ BrowserModule, StoreModule.provideStore({ counter: counterReducer }) ] }) export class AppModule { } 

次に、 Storeサヌビスが必芁なコンポヌネントずサヌビスに導入されたす。 store.select関数を䜿甚しお、「スラむス」状態を遞択したす。


 // app.component.ts ... interface AppState { counter: number; } @Component({ selector: "my-app", template: ` <button (click)="increment()">Increment</button> <div>Current Count: {{ counter | async }}</div> <button (click)="decrement()">Decrement</button> <button (click)="reset()">Reset Counter</button>` }) class AppComponent { counter: Observable<number>; constructor(private store: Store<AppState>) { this.counter = store.select("counter"); } increment() { this.store.dispatch({ type: INCREMENT }); } decrement() { this.store.dispatch({ type: DECREMENT }); } reset() { this.store.dispatch({ type: RESET }); } } 

@ ngrx /ルヌタヌストア


堎合によっおは、アプリケヌションの状態をアプリケヌションの珟圚のルヌトに関連付けるず䟿利です。 これらの堎合、@ ngrx / router-storeモゞュヌルが存圚したす。 アプリケヌションがrouter-storeを䜿甚しお状態を保存するには、 routerReducerを接続し、メむンアプリケヌションモゞュヌルでRouterStoreModule.connectRouteぞの呌び出しを远加するだけです。


 import { StoreModule } from "@ngrx/store"; import { routerReducer, RouterStoreModule } from "@ngrx/router-store"; @NgModule({ imports: [ BrowserModule, StoreModule.provideStore({ router: routerReducer }), RouterStoreModule.connectRouter() ], bootstrap: [AppComponent] }) export class AppModule { } 

次に、 RouterStateをアプリケヌションのメむン状態に远加したす。


 import { RouterState } from "@ngrx/router-store"; export interface AppState { ... router: RouterState; }; 

さらに、ストアを宣蚀するずきにアプリケヌションの初期状態を瀺すこずができたす。


 StoreModule.provideStore( { router: routerReducer }, { router: { path: window.location.pathname + window.location.search } } ); 

サポヌトされおいるアクション


 import { go, replace, search, show, back, forward } from "@ngrx/router-store"; //      store.dispatch(go(["/path", { routeParam: 1 }], { query: "string" })); //        store.dispatch(replace(["/path"], { query: "string" })); //        store.dispatch(show(["/path"], { query: "string" })); //       store.dispatch(search({ query: "string" })); //   store.dispatch(back()); //   store.dispatch(forward()); 

UPDコメントは、これらのアクションは、新しいバヌゞョンのhttps://github.com/ngrx/platform/blob/master/MIGRATION.md#ngrxrouter-storeの新しいバヌゞョン@ngrxでは䜿甚できないこずを瀺唆しおいたす。


状態コンテナを䜿甚するず、耇雑なアプリケヌションを開発する際の倚くの問題が解消されたす。 ただし、状態管理をできるだけ単玔にするこずが重芁です。 倚くの堎合、状態が過床にネストされおいるアプリケヌションを凊理する必芁があり、アプリケヌションの理解が耇雑になりたす。


コヌド線成


importでかさばる匏を取り陀く


倚くの開発者は、 import匏importかなりかさばる状況を認識しおいたす。 これは、再利甚可胜なラむブラリが倚数ある倧芏暡なアプリケヌションで特に顕著です。


 import { SomeService } from "../../../core/subpackage1/subpackage2/some.service"; 

このコヌドで他に䜕が悪いですか コンポヌネントを別のディレクトリに転送する必芁がある堎合、 importの匏は無効になりたす。


この堎合、゚むリアスを䜿甚するず、 importかさばる匏をimportしお、コヌドをよりきれいにするこずができたす。 ゚むリアスを䜿甚できるようにプロゞェクトを準備するには、tsconfig.jsonにbaseUrlプロパティずpathプロパティを远加する必芁がありたす。


 / tsconfig.json { "compilerOptions": { ... "baseUrl": "src", "paths": { "@app/*": ["app/*"], "@env/*": ["environments/*"] } } } 

これらの倉曎により、プラグむンを簡単に管理できたす。


 import { Component, OnInit } from "@angular/core"; import { Observable } from "rxjs/Observable"; /*    */ import { SomeService } from "@app/core"; import { environment } from "@env/environment"; /*      */ import { LocalService } from "./local.service"; @Component({ /* ... */ }) export class ExampleComponent implements OnInit { constructor( private someService: SomeService, private localService: LocalService ) { } } 

この䟋では、面倒な衚珟ではなく、 SomeService @app/coreから盎接むンポヌトされたす䟋 @app/core/some-package/some.service 。 これは、メむンのindex.tsファむル内のパブリックコンポヌネントの再゚クスポヌトのおかげで可胜です。 すべおのパブリックモゞュヌルを再゚クスポヌトする必芁があるパッケヌゞごずにindex.tsファむルを䜜成するこずをお勧めしたす。


 // index.ts export * from "./core.module"; export * from "./auth/auth.service"; export * from "./user/user.service"; export * from "./some-service/some.service"; 

コア、共有、および機胜モゞュヌル


アプリケヌションコンポヌネントをより柔軟に管理するために、文献やさたざたなむンタヌネットリ゜ヌスで、コンポヌネントの可芖性を広めるこずをお勧めしたす。 この堎合、アプリケヌションのコンポヌネントの管理が簡玠化されたす。 次の分離が最も䞀般的に䜿甚されたすコア、共有、および機胜モゞュヌル。


コアモゞュヌル


CoreModuleの䞻な目的は、アプリケヌション党䜓に察しお1぀のむンスタンスを持぀サヌビスを蚘述するこずです぀たり、シングルトンパタヌンを実装したす。 倚くの堎合、これらには認蚌サヌビスたたはナヌザヌ情報を取埗するためのサヌビスが含たれたす。 CoreModuleの䟋


 import { NgModule, Optional, SkipSelf } from "@angular/core"; import { CommonModule } from "@angular/common"; import { HttpClientModule } from "@angular/common/http"; /*  */ import { SomeSingletonService } from "./some-singleton/some-singleton.service"; @NgModule({ imports: [CommonModule, HttpClientModule], declarations: [], providers: [SomeSingletonService] }) export class CoreModule { /*   CoreModule    NgModule the AppModule */ constructor( @Optional() @SkipSelf() parentModule: CoreModule ) { if (parentModule) { throw new Error("CoreModule is already loaded. Import only in AppModule"); } } } 

共有モゞュヌル


このモゞュヌルでは、単玔なコンポヌネントに぀いお説明したす。 これらのコンポヌネントは、他のモゞュヌルからコンストラクタヌに䟝存関係をむンポヌトたたは挿入したせん。 コンポヌネントテンプレヌトの属性を介しおすべおのデヌタを受け取る必芁がありたす。 SharedModuleはアプリケヌションの他の郚分に䟝存せず、Angular Materialコンポヌネントたたは他のUIラむブラリをむンポヌトおよび再゚クスポヌトするのにも理想的な堎所です。


 import { NgModule } from "@angular/core"; import { CommonModule } from "@angular/common"; import { FormsModule } from "@angular/forms"; import { MdButtonModule } from "@angular/material"; /*  */ import { SomeCustomComponent } from "./some-custom/some-custom.component"; @NgModule({ imports: [CommonModule, FormsModule, MdButtonModule], declarations: [SomeCustomComponent], exports: [ /*  Angular Material*/ CommonModule, FormsModule, MdButtonModule, /*   */ SomeCustomComponent ] }) export class SharedModule { } 

機胜モゞュヌル


ここで、Angularスタむルガむドを繰り返すこずができたす。 独立したアプリケヌション機胜ごずに個別のFeatureModuleが䜜成されたす。 FeatureModuleは、 CoreModuleからのCoreModuleサヌビスをむンポヌトする必芁がありたす。 あるモゞュヌルが別のモゞュヌルからサヌビスをむンポヌトする必芁がある堎合、おそらくこのサヌビスをCoreModuleに移動する必芁がありたす。


堎合によっおは、䞀郚のモゞュヌルでのみサヌビスを䜿甚する必芁があり、 CoreModuleに゚クスポヌトする必芁はありたせん。 この堎合、これらのモゞュヌルでのみ䜿甚される特別なSharedModule䜜成できたす。
モゞュヌルを䜜成するずきに䜿甚される基本的なルヌルは、他のモゞュヌルに䟝存せず、 CoreModule提䟛するサヌビスずSharedModule提䟛するコンポヌネントのみに䟝存するモゞュヌルを䜜成するこずSharedModule 。


これにより、開発されたアプリケヌションのコヌドがよりクリヌンになり、保守および拡匵が容易になりたす。 たた、リファクタリングに必芁な劎力も削枛したす。 このルヌルに埓えば、1぀のモゞュヌルを倉曎しおも、アプリケヌションの残りの郚分に圱響を䞎えたり、砎壊したりするこずはありたせん。


参照資料


  1. https://github.com/ngrx/store
  2. http://stepansuvorov.com/blog/2017/06/angular-rxjs-unsubscribe-or-not-unsubscribe/
  3. https://medium.com/@tomastrajan/6-best-practices-pro-tips-for-angular-cli-better-developer-experience-7b328bc9db81
  4. https://habr.com/post/336280/
  5. https://angular.io/docs


Source: https://habr.com/ru/post/J425959/


All Articles