我是新手并且不确定我的方法有什么问题,请建议如何解决以下问题。
这是我想要做的,当我访问主应用程序页面时,它从config.service.ts调用getConfigs()并从后端获取数据更新this.configStringSource.next(config)。之后它会重定向到this.router.navigate([' / clone / status']),我没有从config.service.ts获取数据
如果我使用ngAfterContentChecked,则执行config-resolver.service.ts,执行status.component.ts和config-resolver.service.ts按预期获取正确的数据,但我无法从状态获取相同的数据.component.ts使用this.route.data.subscribe,我得到" undefined"。
请参阅下面的完整代码,我们将非常感谢您的帮助。
export class Config {
configID: string;
sourceDbNodes: string;
targetDbNodes: string;
}
import { Injectable, OnInit } from '@angular/core';
import { Http, Headers, Response } from '@angular/http';
//import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import { Router } from '@angular/router';
import {Subject} from 'rxjs/Subject';
import { Config } from '../_models/config';
@Injectable()
export class ConfigService {
// Observable string source
private configsStringSource = new Subject<Config>();
// Observable string stream
configsString$ = this.configsStringSource.asObservable();
// Service message commands
updateConfigs(configs: Config) {
this.configsStringSource.next(configs)
}
constructor(private http: Http, private router:Router) { }
getConfigs() {
let headers = new Headers();
headers.append('Content-Type','application/json');
return this.http.get('http://localhost:8080/sample1/api/config', { headers: headers })
.map((response: Response) => response.json());
}
getConfig(configID: string) {
this.configsString$.subscribe(
data => {
console.log('config-resolver.service.ts configsString$ = ', data[1]);
return data[1];
});
}
}
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Injectable } from '@angular/core';
import { ConfigService } from './config.service';
import { Config } from '../_models/config';
interface Server {
id: number;
name: string;
status: string;
}
@Injectable()
export class ConfigResolver implements Resolve<Config> {
config: Config;
constructor(private configService: ConfigService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Config> | Promise<Config> | Config {
this.configService.configsString$.subscribe(
data => {
console.log('config-resolver.service.ts data[1] = ', data[1]);
this.config = data[1];
console.log('config-resolver.service.ts this.config = ', this.config);
});
console.log('config-resolver.service.ts this.config = ', this.config);
return this.config;
}
}
...
...
import { ConfigService } from './_services/config.service';
import { ConfigResolver } from './_services/config-resolver.service';
@NgModule({
declarations: [
...
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
AppRouting,
BrowserAnimationsModule,
],
providers: [ConfigService, ConfigResolver],
bootstrap: [AppComponent]
})
export class AppModule { }
import { Routes, RouterModule } from '@angular/router';
import { CloneComponent } from './clone/clone.component';
import { StatusComponent } from './status/status.component';
import { ConfigurationComponent } from './configuration/configuration.component';
import { LogsComponent } from './logs/logs.component';
import { ConfigResolver } from './_services/config-resolver.service';
const appRoutes: Routes = [
{ path: 'clone', component: CloneComponent, children: [
{path: 'status', component: StatusComponent, resolve: {config: ConfigResolver} },
]
},
{ path: 'logstream', component: LogstreamComponent },
];
export const AppRouting = RouterModule.forRoot(appRoutes);
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Config } from './_models/config';
import { ConfigService } from './_services/config.service';
@Component({
moduleId: module.id.toString(),
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
configs: Config[];
constructor(private router:Router, private configService:ConfigService ) { }
title = 'Angular 4 Proeject';
private getConfigs() {
this.configService.getConfigs().subscribe(configs => {
this.configs = configs;
this.configService.updateConfigs(configs);
console.log('app.component.ts sourceDbNode = '+this.configs[0].sourceDbNodes);
});
}
ngOnInit() {
this.getConfigs();
this.router.navigate(['/clone/status']);
}
}
import { Component, Input, OnInit, AfterContentChecked } from '@angular/core';
import { ActivatedRoute, Params, Router, Data } from '@angular/router';
import { Config } from '../_models/config';
import { ConfigService } from '../_services/config.service';
@Component({
selector: 'app-status',
template: `
<p>
status Works! {{config}}
</p>
`,
styleUrls: ['./status.component.scss']
})
export class StatusComponent implements AfterContentChecked {
configs: string;
config: Config;
servers: Array<any>;
server: { id: number; name: string; status: string; };
constructor(private configService:ConfigService,
private route: ActivatedRoute,
private router: Router) { }
ngAfterContentChecked() {
this.route.data.subscribe(
(data: Data) => {
this.config = data['config'];
console.log('status.component.ts data = ', data['config']);
console.log('status.component.ts this.config = ', this.config);
}
);
}
}
accordion.component.ts:54
accordion.component.ts this.accordions = undefined core.es5.js:2925
Angular正在开发模式下运行。调用enableProdMode()以启用生产模式。 配置-resolver.service.ts:69
config-resolver.service.ts this.config = undefined clone.component.ts:20
clone ngOnInit this.config = undefined status.component.ts:79
status.component.ts data = undefined status.component.ts:80
status.component.ts this.config = undefined status.component.ts:79
status.component.ts data = undefined status.component.ts:80
status.component.ts this.config = undefined status.component.ts:79
status.component.ts data = undefined status.component.ts:80
status.component.ts this.config = undefined 配置-resolver.service.ts:64
config-resolver.service.ts data [1] = {configID:&#34; PRODDB_TO_DEVDB&#34 ;, sourceDbNodes:&#34; dbnode21&#34;,targetDbNodes:&#34; dbnode22&#34;} 配置-resolver.service.ts:66
config-resolver.service.ts this.config = {configID:&#34; PRODDB_TO_DEVDB&#34 ;, sourceDbNodes:&#34; dbnode21&#34;,targetDbNodes:&#34; dbnode22&#34;} app.component.ts:27
app.component.ts sourceDbNode = dbnode11 accordion.component.ts:54
status.component.ts data = undefined status.component.ts:80
status.component.ts this.config = undefined
-
提前感谢您的帮助。
答案 0 :(得分:1)
你的解析器错了:
this.configService.configsString$.subscribe(
data => {
this.config = data[1];
});
return this.config;
}
这没有任何意义。您通过订阅一个observable来获取值异步,以便稍后在数据可用时执行回调,并在此异步调用之后立即返回。
正如返回类型的方法所示,只返回一个observable,路由器本身将订阅,并且只有在数据可用时才导航到您的组件:
return this.configService.configsString$.map(
data => data[1];
});
但这只是第一个问题。由于您订阅主题,路由器将等待主题发出下一个事件。但是永远不会有一个,因为您在更新配置之前刚刚发出了最后一个事件。您需要了解有关可观察量如何工作的更多信息。