Angular 16: Service, DI, routing, dan guard
Ringkasan satu halaman. Dari Lesson 0014. Lanjutan dari Angular dasar.
Angular Service + inject
@Injectable({ providedIn: 'root' })
export class ProductService { constructor(private http: HttpClient) {} }
constructor(private products: ProductService) {} // inject lewat tipe
private products = inject(ProductService); // atau fungsi inject()
Di mana provider ditulis
| Tempat | Instance | Padanan |
|---|---|---|
providedIn: 'root' | satu, bersama; tree-shakable (pilihan default) | Provider di <App/>; Singleton .NET |
@NgModule providers | satu per ModuleInjector (modul lazy = injector anak) | gaya sebelum v6 |
@Component providers | satu per instance component, mati bersamanya | <Ctx.Provider> di component itu |
Resolusi (DI hierarkis)
ElementInjector component → parent → … → ModuleInjector (root) → platform → NullInjector (error, kecuali @Optional()). Provider pertama yang ditemukan menang, seperti useContext membaca Provider terdekat. Modifier: @Optional, @Self, @SkipSelf, @Host.
Routing
const routes: Routes = [
{ path: 'products', component: ProductListComponent },
{ path: 'products/:id', component: ProductDetailComponent },
{ path: 'admin', canMatch: [authGuard], canActivate: [authGuard],
loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule) },
{ path: '', redirectTo: 'products', pathMatch: 'full' },
{ path: '**', component: PageNotFoundComponent }, // terakhir: first-match wins
];
imports: [RouterModule.forRoot(routes)] // root; modul fitur: RouterModule.forChild(routes)
| Angular | React Router |
|---|---|
routerLink="/products" | <Link to> |
<router-outlet> | <Outlet /> |
ActivatedRoute.snapshot.paramMap.get('id') / paramMap.pipe(...) | useParams() |
router.navigate(['/products', id]) | navigate() |
loadChildren + import() | React.lazy |
Lazy loading: hapus modul dari imports AppModule, kalau tidak ia ikut bundle awal.
Guard
export const authGuard: CanActivateFn = () => {
const auth = inject(AuthService), router = inject(Router);
return auth.isLoggedIn ? true : router.parseUrl('/login');
};
| Return | Efek |
|---|---|
true | navigasi lanjut |
false | berhenti, user tetap di tempat |
UrlTree | batal + navigasi baru (redirect) |
Observable / Promise | router menunggu nilai pertama |
canActivate masuk route · canActivateChild masuk child · canDeactivate keluar route · resolve ambil data sebelum aktif · canMatch route dipakai atau tidak (dicek sebelum modul lazy dimuat; canLoad deprecated).
Jebakan interview
- Service di
providersmodule yang juga di-import modul lazy → dua instance. PakaiprovidedIn: 'root'. RouterModule.forRootdi modul fitur → seharusnyaforChild(hanya boleh satuRouter).- Wildcard
**di atas route lain → route lain tidak pernah cocok. - Menulis guard baru sebagai
class … implements CanActivate→ deprecated di v16; pakaiCanActivateFn. - Hanya
canActivatedi route lazy → bundle tetap terunduh; tambahcanMatch. - Guard dianggap keamanan → guard hanya navigasi di browser; otorisasi tetap di API.
Sumber: Understanding DI · Hierarchical injectors · Singleton services · Common routing tasks · Lazy loading · Route guards · CanActivate (deprecated) (dokumentasi Angular v16)