我有一个快速服务器和Angular 4应用程序,它们在一个项目中共存。它基于这个启动器: https://github.com/vladotesanovic/angular2-express-starter
我遇到的问题是,当Angular发帖或获取时,它会发射两次。
您可以想象在发帖时这是一个什么问题!
这是我的组成部分:
import { Component, OnInit } from '@angular/core';
import { Settings } from '../shared/settings/settings';
import { SettingsService } from '../shared/settings/settings.service';
import { Observable } from 'rxjs/Observable';
@Component({
templateUrl: './welcome.component.html',
styleUrls: ['./welcome.component.scss']
})
export class WelcomeComponent implements OnInit {
settings: Observable<Settings[]>;
error: any;
constructor(
private settingsService: SettingsService) {
}
ngOnInit() {
this.getSettings();
}
getSettings() {
this.settings = this.settingsService.getSettings();
}
}
服务是:
import { Injectable } from '@angular/core';
import { Headers, Http, Response } from '@angular/http';
import 'rxjs/add/operator/catch';
import { Settings } from './settings';
import {Observable} from 'rxjs/Rx';
import { ErrorComponent } from '../error/error.component';
import { MdDialog, MD_DIALOG_DATA } from '@angular/material';
@Injectable()
export class SettingsService {
constructor(private http: Http, private dialog: MdDialog) { }
extractData(res: Response) {
return res.json();
}
getSettings(): Observable<Settings[]> {
return this.http.get('/api/getSettings').map(this.extractData).catch(error => this.handleError(error));
}
private handleError(error: any): Promise<any> {
const dialog = this.dialog.open(ErrorComponent, {
data: {
error: error
}
});
return Promise.reject(error.message || error);
}
}
app.module是:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpModule } from '@angular/http';
import { MaterialModule } from '@angular/material';
import 'hammerjs';
import { AppRoutingModule } from './app-routing.module';
import { FlexLayoutModule } from '@angular/flex-layout';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { SettingsService } from './shared/settings/settings.service';
import { AppComponent } from './app.component';
import { WelcomeComponent } from './welcome/welcome.component';
import { OrderComponent } from './order/order.component';
import { ErrorComponent } from './shared/error/error.component';
import { SuccessComponent } from './shared/success/success.component';
import { TextMaskModule } from 'angular2-text-mask';
import { LoadingBarHttpModule } from '@ngx-loading-bar/http'; //https://github.com/aitboudad/ngx-loading-bar
import {enableProdMode} from '@angular/core';
@NgModule({
declarations: [
AppComponent,
WelcomeComponent,
OrderComponent,
ErrorComponent,
SuccessComponent
],
imports: [
BrowserModule,
HttpModule,
MaterialModule,
AppRoutingModule,
FlexLayoutModule,
BrowserAnimationsModule,
FormsModule,
ReactiveFormsModule,
TextMaskModule,
LoadingBarHttpModule
],
providers: [
SettingsService
],
bootstrap: [
AppComponent
],
entryComponents: [
ErrorComponent,
SuccessComponent
]
})
export class AppModule { }
对于服务器端,我可以添加更多代码或将整个帖子发布到GitHub,但proxy.conf.json和package.json与他的启动器基本相同。我的猜测是模块正在加载或者我使用Observables错误了吗?
的package.json:
"scripts": {
"start": "concurrently --kill-others \"npm run _server:run\" \"ng serve --aot=false --progress=false --proxy-config proxy.conf.json\"",
"lint:client": "ng lint",
"lint:server": "tslint './server/**/*.ts' -c ./server/tslint.json --fix",
"test:client": "ng test",
"e2e:client": "ng e2e",
"build": "ng build --prod --sm=false --aot --output-path=dist/client && npm run _server:build",
"_server:run": "tsc -p ./server && concurrently \"tsc -w -p ./server\" \"nodemon --delay 5 dist/server/bin/www.js\" ",
"_server:build": "tsc -p ./server",
"postinstall": "npm run build"
},
proxy.json.conf:
{
"/api": {
"target": "http://localhost:4300",
"secure": false
}
}
即使我使用Promises执行此操作,我仍然遇到同样的问题,这让我觉得它仍然是路由器或app.module中的东西。
export class WelcomeComponent implements OnInit {
settings: Settings[];
error: any;
constructor(
public dialog: MdDialog,
private router: Router,
private settingsService: SettingsService) {
console.log('calling constructor');
}
async ngOnInit(): Promise<void> {
console.log('calling onInit');
this.getSettings();
}
async getSettings(): Promise<void> {
this.settingsService.getSettings()
.then(result => this.settings = result)
.catch(error => this.handleError(error));
}
}
这是服务
async getSettings(): Promise<Settings[]> {
console.log('calling SettingsService');
try {
const response = await this.http
.get('/api/getSettings')
.toPromise();
return response.json() as Settings[];
} catch (error) {
await this.handleError(error);
}
}
答案 0 :(得分:0)
您在Chrome开发工具中看到两次调用触发的事实意味着问题出在客户端。
我的建议是订阅该调用,而不是将返回的observable分配给本地属性。 然后,您可以在调用服务的方法的入口点处创建一个断点。一旦命中,请查看调用堆栈以查看谁正在解雇呼叫。 我猜你会看到两次调用getSettings()的OnInit方法。 在这种情况下,我会假设您的组件由于某种原因在您的应用程序中被创建了两次。
答案 1 :(得分:0)
罪魁祸首原来是第三方: https://github.com/aitboudad/ngx-loading-bar
如果您使用的是ngx-loading-bar,则LoadingBarHttpModule将导致此行为。我还没有设法让LoadingBarHttpClientModule工作。