Angular2 RC6 HttpModule ручной впрыск
Я перевожу проект с angular2 RC4 на RC6, и у меня есть специальный Form Validator, который требует Http
, До миграции я использовал ReflectiveInjector
с HTTP_PROVIDERS
, но с RC6 это уже невозможно, так как HTTP_PROVIDERS
устарела, соответственно больше не присутствует. Это статический метод в Валидаторе:
static checkVat(control: FormControl) {
let checkVatUrl = "http://localhost:8080/checkvat";
let injector = ReflectiveInjector.resolveAndCreate([HTTP_PROVIDERS]);
let http = injector.get(Http);
let authHttp = new AuthHttp(new AuthConfig(), http);
if (control.value === "") {
return new Observable((obs: any) => {
obs.next(null);
obs.complete();
});
} else {
return authHttp.get(checkVatUrl + "/" + control.value)
.map((data: Response) => {
if (data.json().valid) {
return null;
} else {
let reason = "isNotValidVat";
return {[reason]: true};
}
})
.catch(function (e) {
return new Observable((obs: any) => {
obs.complete();
});
});
}
}
Просто заменив HTTP_PROVIDERS
с HttpModule
не сработало, я обнаружил подобную проблему здесь в stackru ( NG2 RC5: HTTP_PROVIDERS устарела) в отношении тестирования, но единственный ответ специфичен для тестирования.
Как мне вручную "залить" Http
или же HttpModule
с RC6, если есть другое или лучшее решение для этого пользовательского Validator, я тоже открыт для этого.
Заранее спасибо.
ОБНОВЛЕНИЕ: checkVat
Метод статический, поэтому мне пришлось использовать ReflectiveInjector, а не просто внедрить его через конструктор, как и везде. Пользовательский валидатор используется следующим образом:
this.vatCtrl = new FormControl("", Validators.compose([Validators.pattern(this.vatService.vatPattern)]),VatValidator.checkVat);
ОБНОВЛЕНИЕ 2: С помощью ответа Гюнтера Цохбауэра я изменил Код следующим образом, чтобы он работал без статической функции и не требовал ручного введения:
Валидатор:
@Injectable()
экспортный класс VatValidator {
constructor(private http: Http) {
}
checkVat(control: FormControl) {
let checkVatUrl = "http://localhost:8080/checkvat";
let authHttp = new AuthHttp(new AuthConfig(), this.http);
if (control.value === "") {
return new Observable((obs: any) => {
obs.next(null);
obs.complete();
});
} else {
return authHttp.get(checkVatUrl + "/" + control.value)
.map((data: Response) => {
if (data.json().valid) {
return null;
} else {
let reason = "isNotValidVat";
return {[reason]: true};
}
})
.catch(function (e) {
return new Observable((obs: any) => {
obs.complete();
});
});
}
}
}
В компоненте, который имеет FormControl:
constructor(private vatValidator: VatValidator) {
this.vatCtrl = new FormControl("", Validators.compose([Validators.pattern(vatPattern)]), this.vatValidator.checkVat.bind(this.vatValidator));
}
3 ответа
Если вы немного измените свой класс валидатора, вам не нужен статический метод
@Injectable()
class PatternValidator {
constructor(private http:Http){}
// this is a method that returns a validator function
// configured with a pattern
pattern(pattern) {
return (control:Control) => {
this.http.get(...)
...
}
}
}
Вы можете использовать его как:
- внедрить его в ваш компонент, чтобы DI передавал его зависимости в (
Http
)
constructor(private pattern:PatternValidator) {}
- передать это с
bind(pattern)
так.this
продолжает работать внутри функции валидатора
this.vatCtrl = new FormControl("",
Validators.compose([
this.pattern(this.vatService.vatPattern).bind(this.pattern)
]), VatValidator.checkVat);
Смотрите также Inject Http вручную в угловых 2
import { ReflectiveInjector } from '@angular/core';
import { Http, XHRBackend, ConnectionBackend, BrowserXhr, ResponseOptions, XSRFStrategy, BaseResponseOptions, CookieXSRFStrategy, RequestOptions, BaseRequestOptions } from '@angular/http';
class MyCookieXSRFStrategy extends CookieXSRFStrategy {}
...
let http = ReflectiveInjector.resolveAndCreate([
Http, BrowserXhr,
{ provide: ConnectionBackend, useClass: XHRBackend },
{ provide: ResponseOptions, useClass: BaseResponseOptions },
{ provide: XSRFStrategy, useClass: MyCookieXSRFStrategy },
{ provide: RequestOptions, useClass: BaseRequestOptions }
]).get(Http);
Конечно, вам все еще нужен HttpModule, наслаждайтесь!
С и после RC5, что вы можете сделать, это
import { HttpModule} from '@angular/http';
@NgModule({
imports: [ BrowserModule,HttpModule ], //<------HttpModule
declarations: [ AppComponent],
providers: [service],
bootstrap: [ AppComponent ]
})
И в сервисе или компоненте,
import { Http, Response } from '@angular/http';
@Injectable()
export class service{
constructor(private http:Http){} //<----inject here
// use http here
}