angular2-chapter10

2017-05-06  本文已影响0人  wghglory

How angular 2 do DI

Check code at: https://github.com/wghglory/angular2-fundamental

when calling eventService, angular2 uses EventService class as key to do DI, it creates an instance of EventService, and assign it to eventService. (angular1 uses string as key to do DI)

export class CreateEventComponent {
    constructor(private eventService: EventService) { }
}

Using Third Party Global Services - The Problem

Using OpaqueToken for DI

  1. Update common/toastr.service.ts
// import { Injectable } from '@angular/core'
//
// //I guess this local variable was assigned the global toastr variable
// declare let toastr: any
//
// @Injectable()
// export class ToastrService {
//
//     success(message: string, title?: string) {
//         toastr.success(message, title);
//     }
//     info(message: string, title?: string) {
//         toastr.info(message, title);
//     }
//     error(message: string, title?: string) {
//         toastr.error(message, title);
//     }
//     warning(message: string, title?: string) {
//         toastr.warning(message, title);
//     }
//
// }

import { OpaqueToken } from '@angular/core'

export let TOASTR_TOKEN = new OpaqueToken('toastr');

//not necessary if api is large, just for intellisense
export interface Toastr {
    success(message: string, title?: string): void;
    info(message: string, title?: string): void;
    error(message: string, title?: string): void;
    warning(message: string, title?: string): void;
}
  1. Register it in app.module.ts
// import { ToastrService } from './common/toastr.service'
+ import { TOASTR_TOKEN, Toastr } from './common/toastr.service'
+ declare let toastr: Toastr

@NgModule({
    imports: [...],
    declarations: [...],
    providers: [
        EventService,
        // ToastrService,
+        { provide: TOASTR_TOKEN, useValue: toastr },
        EventRouteActivator,
        {
            provide: 'canDeactivateCreateEvent',
            useValue: checkDirtyState
        },
        EventListResolver,
        AuthService
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }
  1. Remove all old ToastService in events-list component

Using the @Inject Decorator

profile.component.ts:

  1. import Inject, TOASTR_TOKEN, Toastr.
  2. @Inject(TOASTR_TOKEN) private toastr: Toastr, @Inject is angular DI, Toastr is typescript intellisense (not required)
  3. use the service: this.toastr.success('Profile saved successfully!')
+ import { Component, OnInit, Inject } from '@angular/core'
import { FormControl, FormGroup, Validators } from '@angular/forms'
import { AuthService } from './auth.service'
import { Router } from '@angular/router'

+ import { TOASTR_TOKEN, Toastr } from '../common/toastr.service'

@Component({
    templateUrl: 'app/user/profile.component.html',
    styles: [
        `
        em {float:right;color:#e05c65;padding-left:10px;}
        .error input{background-color:#e3c3c5;}
        .error ::-webkit-input-placeholder {color:#999;}
        .error ::-moz-placeholder {color:#999;}
        .error :-ms-input-placeholder {color:#999;}
        `
    ]
})
export class ProfileComponent implements OnInit {
+    constructor(private authService: AuthService, private router: Router, @Inject(TOASTR_TOKEN) private toastr: Toastr) { }

    profileForm: FormGroup
    private firstName: FormControl
    private lastName: FormControl

    ngOnInit() {
        this.firstName = new FormControl(this.authService.currentUser.firstName, [Validators.required, Validators.pattern('[a-zA-Z].*')])
        this.lastName = new FormControl(this.authService.currentUser.lastName, Validators.required)

        this.profileForm = new FormGroup({
            firstName: this.firstName,
            lastName: this.lastName
        })
    }

    cancel() {
        this.router.navigate(['events'])
    }

    saveProfile(formValues) {
        if (this.profileForm.valid) {
            this.authService.updateCurrentUser(formValues.firstName, formValues.lastName)
    +        this.toastr.success('Profile saved successfully!')
    -        // this.router.navigate(['events'])
        }
    }

    validateFirstName() {
        return this.firstName.valid || this.firstName.untouched
    }

    validateLastName() {
        return this.lastName.valid || this.lastName.untouched
    }
}

The useClass Provider

in app.module.ts:

Someday we might use { provide: logger, useClass: fileLogger }

providers: [
    EventService,
    // ToastrService,
    { provide: TOASTR_TOKEN, useValue: toastr },
    EventRouteActivator, //short hand of { provide: EventRouteActivator, useClass: EventRouteActivator },
    {
        provide: 'canDeactivateCreateEvent',
        useValue: checkDirtyState
    },
    EventListResolver,
    AuthService
],

The useExisting and useFactory Providers (rarely use)

You use Logger service. It's a big api which contains 30 methods, but you are going to use only 5 common methods

providers: [
    { provide: MinimalLogger, useExisting: Logger },
    { provide: MinimalLogger, useFactory: Logger },
],
上一篇下一篇

猜你喜欢

热点阅读