我想知道从服务器获取响应后加载表单的最佳方法是什么。我写了一些代码从服务器获取数据,在我的组件中我订阅了响应,但是我的UI在加载之前就已经加载了。
我想使用此组件进行添加和编辑。
组件:
@Component({
selector: 'gate',
templateUrl: '/public/app/views/gate.html',
directives: [GateFormComponent, StrategyComponent],
providers : [MyService]
})
export class MyComponent {
private id:any;
constructor(private _routeParams:RouteParams, @Inject(MyModel) private myModel,
private myService : MyService) {
}
ngOnInit() {
this.id = this._routeParams.get("id");
if (this.id) {
this.gateDataModel.unique_display_id = parseInt(this.id);
this.myService.loadData(this.id)
.subscribe(response => console.log(response));
}
}
在我的组件中,我正在加载2个组件,其中一个组件有一个表单,一旦得到响应,我必须加载数据。所有这些只有在我有身份证时才会发生。
服务
@Injectable()
export class MyService extends HTTPServices {
constructor(http:Http) {
super(http);
}
loadData(id:number) {
return this.query(url)
.map(res => res.json())
.catch(this.handleError)
}
private handleError(error:Response) {
console.log("Error : ", error);
return Observable.throw(error.text());
}
HTTPServices
export class HTTPServices {
private headers:Headers;
private http:Http;
defaultOptionsArgs:RequestOptionsArgs;
constructor(http:Http) {
this.http = http;
this.headers = new Headers();
this.headers.append('Content-Type', 'application/json');
this.defaultOptionsArgs = {
'headers': this.headers
};
}
create(servicePath:string, model:any, options?:RequestOptionsArgs) {
var url = this.getUrl(servicePath);
var options = options ? options : this.defaultOptionsArgs;
return this.http.post(url, JSON.stringify(model), options);
}
query(servicePath:string, options?:RequestOptionsArgs) {
var options = options ? options : this.defaultOptionsArgs;
return this.http.get(servicePath, options);
}
}
---- -----已编辑
最后,我能够添加@CanActivate
并且它正在运行。
@Component({
selector: 'gate',
templateUrl: '/public/app/views/gate.html',
directives: [ROUTER_DIRECTIVES, GateFormComponent, StrategyComponent]
})
@CanActivate(
(next: ComponentInstruction, prev: ComponentInstruction) => {
return new Promise((resolve) => {
let id = next.params["id"];
let injector = ReflectiveInjector.resolveAndCreate([HTTP_PROVIDERS]);
let http = injector.get(Http);
if(id){
http.get(URL)
.subscribe((response) => {
console.log(response)
next.routeData.data["response"] = response;
// continue
resolve(true);
}, (error) => {
resolve(false);
});
} else {
resolve(true);
}
});
}
)
export class MyComponent{
private id:any;
constructor(private _routeParams:RouteParams, @Inject(MyModel) private myModel, routeData: RouteData) {
console.log(routeData.get("response"));
}
}
组件正在加载,然后我收到响应
由于
答案 0 :(得分:0)
在你的组件中你可以使用
template: `
<div *ngIf="data">
<!-- form goes here -->
</div>
`
其中data
是一个属性,当服务器的响应到达时,该属性被设置为某个值。
答案 1 :(得分:0)
如果您利用Angular2路由(似乎是这种情况),您可以使用OnActivate
接口及其routerOnActivate:
定义路由生命周期方法routerOnActivate,路由器在成功路由导航结束时调用。
对于单个组件的导航,根据CanReuse的结果,将只调用OnActivate或OnReuse中的一个。
使用两个ComponentInstructions作为参数调用routerOnActivate挂钩,第一个表示导航到的当前路由,第二个参数表示前一个路由或null。
如果routerOnActivate返回一个promise,路由更改将一直等到promise实例化并激活子组件。
您可以返回在您的数据存在时将解决的承诺。这是一个示例:
@Component({ ... })
export class MyComponent {
private id:any;
constructor(private _routeParams:RouteParams,
@Inject(MyModel) private myModel,
private myService : MyService) {
}
routerOnActivate() {
this.id = this._routeParams.get("id");
return new Promise((resolve, reject) => {
if (this.id) {
this.gateDataModel.unique_display_id = parseInt(this.id);
this.myService.loadData(this.id)
.subscribe(response => {
console.log(response);
resolve();
});
} else {
resolve();
}
});
}
(...)
}
答案 2 :(得分:0)
我有一个类似的问题,但由于该解决方案也可用于您的用例,我建议您查看已接受的答案:How to manipulate a component on specific routes in Angular2
基本思想是扩展router-outlet
指令并覆盖activate()
函数,该函数将在激活下一个路由之前调用,并等待解析的承诺。
例如,您可以这样做:
@Directive({
selector: 'custom-router-outlet'
})
export class CustomRouterOutlet extends RouterOutlet {
private parentRouter:Router;
constructor(_elementRef: ElementRef,
_loader: DynamicComponentLoader,
_parentRouter: Router,
@Attribute('name') nameAttr: string,
private _myRoutingService:MyRoutingService) {
super(_elementRef, _loader, _parentRouter, nameAttr);
this.parentRouter = _parentRouter;
}
activate(nextInstruction: ComponentInstruction): Promise<any> {
let someRouteSpecificData = nextInstruction.routeData.data['someRouteData'];
if(someRouteSpecificData) {
_myRoutingService.beforeRoute(someRouteSpecificData).subscribe( () => {
// go on after this has been resolved
return super.activate(nextInstruction);
// or maybe cancel the route:
return false;
// or maybe do something crazy:
nextInstruction.componentType = MyOtherComponent;
return super.activate(nextInstruction);
}
}
return super.activate(nextInstruction);
}
}
我认为你可以轻松改变这个目的。例如,您可以利用@RouteConfig
来保存有关应该发生什么或在路线更改时检查的信息。
另一种方法是使用这里提到的@CanActivate
装饰器,但它有点难以完成。在这一点上,它只是感觉有点hacky。如果您有兴趣,我可以稍后再添加。
答案 3 :(得分:0)
我已经能够使用路由器的解析功能(https://angular.io/docs/ts/latest/guide/router.html#!#resolve-guard)来实现这一点。这使得http调用成为可能,并且路由仅在http调用observable返回时完成。
这里有很好的例子:https://angular.io/resources/live-examples/router/ts/plnkr.html