角度大师在这方面非常感谢你的帮助。
这是我想要做的,当我访问主应用页面时,它从config.service.ts调用getConfigs()并从后端获取数据然后更新this.configStringSource.next(config)。在那之后我试图将它重定向到this.router.navigate(['/ clone / status']),但没有发生重定向。
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);
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 BehaviorSubject<Config>({ configID: "", sourceDbNodes: "", targetDbNodes: ""});
// 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());
}
}
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 {
return this.configService.configsString$.map(
data => data[1]);
}
}
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 OnInit {
configs: string;
config: Config;
servers: Array<any>;
server: { id: number; name: string; status: string; };
constructor(private configService:ConfigService,
private route: ActivatedRoute,
private router: Router) { }
ngOnInit() {
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);
}
);
}
}
答案 0 :(得分:5)
您的问题是已解析的observable需要完成,所以您只需要将.take(1)或.first()添加到您的解析器可观察对象中,如:
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Config> | Promise<Config> | Config {
return this.configService.configsString$.map(
data => data[1]).take(1);
}
但是,加载配置服务的方式更为简洁:
import { Injectable, APP_INITIALIZER } from '@angular/core';
import { Config } from './_models/config';
@Injectable()
export class ConfigService {
protected config: Config;
constructor(private http: Http) {
}
getConfigs(): Observable<any> {
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());
}
public load() {
return new Promise((resolve, reject) => {
this.getConfigs()
.subscribe(
config => {
this.config = config;
resolve(true);
},
err => resolve(err)
);
});
}
}
export function ConfigServiceInitFactory(configService: ConfigService) {
return () => configService.load();
}
export const ConfigServiceInitProvider = {
provide: APP_INITIALIZER,
useFactory: ConfigServiceInitFactory,
deps: [ConfigService],
multi: true
}
然后在你的app模块中,导入ConfigService和ConfigServiceInitProvider并像这样提供它们:
providers: [
ConfigService,
ConfigServiceInitProvider,
... remaining service providers..
]
这将确保您的配置在其他任何事情之前加载,并且您可以在需要的地方注入配置服务,并且配置将始终以同步方式提供。
答案 1 :(得分:1)
对我有帮助。 在 config.service 更改
// Observable string stream
configsString$ = this.configsStringSource.asObservable();
到stack。
将 .first()添加到 .asObservable()。