在angular2 http响应后填写表格(Fill form after http respons

2019-09-26 05:44发布

我想知道什么是正从服务器的响应后加载形式的最佳方式。 我写了一些代码,它从服务器获取数据,并在我的组件,我订阅的反应,但我的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个组件其中之一有一个形式到我有一次我得到的回应加载数据。 如果我有可用的一个id这一切应该只发生。

服务:

@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"));
}

}

该组件加载了,然后我得到的响应

谢谢

Answer 1:

在你的组件,您可以只使用

template: `
 <div *ngIf="data">
  <!-- form goes here -->
 </div>
`

其中data是在来自服务器的响应到达被设置为某个值的属性。



Answer 2:

如果利用Angular2路由(这似乎是这样),你可以使用杠杆的OnActivate接口及其routerOnActivate:

定义路径的生命周期方法routerOnActivate,其由路由器在一个成功的路线导航的端调用。

对于单个分量的导航,只有要么OnActivate或OnReuse之一将根据CanReuse的结果被调用。

所述routerOnActivate钩被称为具有两个ComponentInstructions作为参数,所述第一表示被导航到当前路线,以及表示先前的路由或空的第二参数。

如果routerOnActivate返回一个承诺,路线变化将等到承诺平息实例化和激活子组件。

你可以返回您的数据将在那里将要解决的承诺。 下面是一个例子:

@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();
      }
    });
  }

  (...)
}


Answer 3:

我有一个类似的问题,但由于该解决方案可用于您的用例太多,我建议看看接受的答案: 如何处理在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装饰喜欢这里已经提到的,但它有点难以完成的任务。 我就觉得在这一点上有点哈克。 如果你有兴趣,我可以在以后添加此。



Answer 4:

我已经能够实现这个使用路由器(的决心功能https://angular.io/docs/ts/latest/guide/router.html#!#resolve-guard )。 这使得HTTP调用的提出和路由仅完成HTTP调用观察到返回时。

这里有很好的例子: https://angular.io/resources/live-examples/router/ts/plnkr.html



文章来源: Fill form after http response in angular2