我正在Angular中构建企业应用程序。我似乎找不到任何人发布了类似的情况,我可以适应以帮助解决我遇到的问题。
应用功能 这是一个基本的角度应用程序,它通过提交表单对Solr后端进行httpGet调用,并通过组件视图显示结果。
问题: 初始httpGet调用是从具有种子数据的根组件(fbsearch索引)触发的。这适用于结果组件中按设计呈现的结果。浏览器开发人员工具的NETWORK部分捕获请求参数并返回200。
当表单传递查询参数时,会出现此问题。我可以通过console.log语句跟踪整个过程中的参数。我注意到当应该触发函数(getHttpResponseDocs)时它不是。 NETWORK部分未显示请求已作出的指示。这似乎表明subscribe()函数没有按设计工作。
我注意到的另一个异常(我不明白其中的含义)是从初始httpGet单击控制台中捕获的Solr queryString时 - url重定向到NETWORK选项卡。当从表单参数构建Solr queryString时,在控制台中单击它将返回Solr的响应。
我不知道这是如何适应这个问题的 - 但我想提到它。我对Angular很新,所以我不熟悉这些类型的应用程序的故障排除。但据我所知 - 问题是指向订阅的问题。我只是不知道如何解决这个问题。
完整的代码可以在这里找到:https://github.com/r2c0der/mvc_fbsearch。
注意: 测试时,输入必须以大写字母开头(Solr事物)。这在生产代码中得到解决。此外,只需要姓氏。
输入表单组件
import { Component, OnInit } from '@angular/core';
import {FormControl, FormGroup} from "@angular/forms";
import {MVCFBSearchQueryParamsService} from "../../services/fbsearch-query-params.service";
import {FBSearchQueryParamsModel} from "../../services/model/fbsearch-query-params.model";
import {MVCFBSearchSolrService} from "../../services/fbsearch-solr.service";
@Component({
selector: 'mvc-fbsearch-query-form',
templateUrl: './fbsearch-query-form.component.html',
styleUrls: ['./fbsearch-query-form.component.css']
})
export class MVWFBSearchQueryFormComponent implements OnInit {
//populating the dropdown menus in the UI
states = [];
years = [];
fbsearchQueryForm:FormGroup;
constructor(
private _queryParamService: MVCFBSearchQueryParamsService,
private _solrService: MVCFBSearchSolrService) { }
ngOnInit() {
//populating the dropdown menus in the UI
this.states = statesAry;
this.years = yearAry;
this.buildForm();
}
//buildform() - assembles the inputs into form group
onSubmit(formValues: FBSearchQueryParamsModel){
//Informs FBSeachIndex to uncollapse filters on form submission
this._queryParamService.formSubmitted.next(true);
let queryParams: FBSearchQueryParamsModel = {
fbLastName: formValues.fbLastName,
fbFirstName: formValues.fbFirstName,
fbState: formValues.fbState,
fbYear: formValues.fbYear
}
this._solrService.buildQueryString(queryParams);
}
}
const statesAry = [
{abbrev: '', option: ''},
{abbrev: 'al', option: 'Alabama'},
{abbrev: 'ar', option: 'Arkansas'},
{abbrev: 'ca', option: 'California'},
{abbrev: 'co', option: 'Colorado'},
{abbrev: 'ct', option: 'Connecticut'}
];
const yearAry = [
{abbrev: '', option: ''},
{option: '186*'},
{option: '1863'},
{option: '1864'},
{option: '1865'}
];
输入表单Component.html
<div class="container">
<div class="row">
<div class="col-lg-3 col-md-3 col-sm-12 col-xs-12">
<fieldset>
<label for="query_form" class="nmaahc_fbsearch_form-label"> Search the Records </label>
<!-- SEARCH FORM -->
<form novalidate [formGroup]="fbsearchQueryForm" (ngSubmit)="onSubmit(fbsearchQueryForm.value)" class="form-horizontal" autocomplete="off" name="nmaahc_fb_query-form" id="query_form" >
<div class="form-group" >
<input formControlName="fbLastName" type="text" class="form-control form-control-lg " name="fbLastName" id="fbLastName" placeholder="Last Name" required />
</div> <!-- lastName -->
<br />
<div class="form-group" >
<input formControlName="fbFirstName" type="text" class="form-control form-control-lg" name="fbFirstName" id="fbFirstName" placeholder="First Name" />
</div> <!-- firstName -->
<br />
<div class="form-group">
<label for="fbState" class="control-label nmaahc_fbsearch_form-label ">State </label>
<select formControlName="fbState" id="fbState" class="nmaahc_fbsearch_form-options form-control" name="fbState" id="fbState">
<option *ngFor="let state of states" [value]="state.option">{{state.option}}</option>
</select>
</div><!-- state -->
<div class="form-group">
<label for="fbYear" class="control-label nmaahc_fbsearch_form-label float-label-control">Year </label>
<select formControlName="fbYear" id="fbYear" class="nmaahc_fbsearch_form-options form-control" name="fbYear" id="fbYear">
<option *ngFor="let year of years" [value]="year.option">{{year.option}}</option>
</select>
</div><!-- year -->
<div class="form-group"> <!-- Submit button !-->
<button type="submit" id="btnSubmit" class="btn nmaahc_fbsearch_form-btn"
>Submit Query</button>
<button type="reset" id="btnReset" class="btn nmaahc_fbsearch_form-btn" >Clear Query</button>
</div> <!-- buttons -->
</form><!-- END FORM -->
</fieldset> <!-- fieldset -->
</div><!-- COLUMN FIRST -->
</div>
</div><!-- FBSEARCH_FORM -->
SolrService
import {Injectable, OnInit} from '@angular/core';
import {FBSearchQueryParamsModel} from "./model/fbsearch-query-params.model";
import {Observable} from "rxjs/Observable";
import {Http} from "@angular/http";
import 'rxjs/add/operator/map';
import {FBSearchHttpResponseModel} from "./model/fbsearch-response.model";
@Injectable()
export class MVCFBSearchSolrService implements OnInit {
queryUrl: string;
private solrBaseUrl = 'http://fbsearch.nmaahc.si.edu:8089/solr/aws_freedmens_fbs';
private solrQueryType = '/select?';
constructor(private _http: Http) { }
ngOnInit(): void {}
buildQueryString(queryParams: FBSearchQueryParamsModel){
console.log('SolrService - BuildQueryString')
let firstname = queryParams.fbFirstName;
console.log(firstname);
let lastname = queryParams.fbLastName;
console.log(lastname);
let year = queryParams.fbYear;
console.log(year);
let state = queryParams.fbState;
console.log(state);
let queryAppend = "fq=FB_FIRST_NAME:"+firstname+"*&indent=on&q=FB_LAST_NAME:"+lastname+"*&wt=json";
// console.log(queryAppend);
let queryString = this.solrBaseUrl+this.solrQueryType+queryAppend;
// console.log(queryString);
this.queryUrl = queryString;
// console.log(this.queryUrl);
}
getHttpResponseDocs():Observable<FBSearchHttpResponseModel[]>{
return this._http.get(this.queryUrl)
.map((response)=>response.json());
}
}
结果列表组件
import {Component, OnInit} from '@angular/core';
import {MVCFBSearchSolrService} from "../../services/fbsearch-solr.service";
import "rxjs/add/operator/do";
@Component() //has the expected metadata
export class MVCFBSearchResultsListComponent implements OnInit {
results$:any[];
constructor(private _solrService: MVCFBSearchSolrService) { }
ngOnInit() {
this._solrService.getHttpResponseDocs()
.map((data)=>{
this.results$ = data;
})
.subscribe((res)=>console.log(res));
}
}
结果列表Component.html
<div >
<h2>Results List Component</h2>
<p *ngIf="(numFound$ | async) as numFound; else noneFound ">
Your search returned {{ numFound }} record(s).
<br /> <em>Displaying {{ rows$ | async }} of {{ numFound }} records.</em> </p>
<div *ngFor="let response of (results$ | async ) ">
<div class="well hoverwell nmaahc_fb_results-thumbnail">
<!--- RECORD HEADER -->
<h4 class="nmaahc_fb_pub-title"> {{response.FB_PUB_TITLE}}</h4>
<h3 class="nmaahc_fb_name">{{response.FB_FIRST_NAME}} {{response.FB_LAST_NAME}}</h3>
<div *ngIf="response?.FB_RECORD_TYPE"><span> {{response.FB_RECORD_TYPE}}</span></div>
<br />
<div *ngIf="response?.FB_RECORD_STATE"> <span>{{response.FB_RECORD_STATE}}</span></div>
</div>
</div>
<ng-template #noneFound>
<p>No records were found to match your search.</p>
</ng-template>
</div>
模型
export interface FBSearchQueryParamsModel {
fbFirstName?: string;
fbLastName: string;
fbState?: string;
fbYear?: string;
fbPubNum?:string;
}
export interface FBSearchResponseModel {
response:[
{
numFound:number;
start:number;
docs:FBSearchResultsModel[]
}
];
}
export interface FBSearchResponseHeaderModel {
responseHeader:[{
status:number;
QTime: number;
params:string[];
}];
}
索引组件
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'mvc-fbsearch-index',
template:`
<!--<fbsearch-header></fbsearch-header>-->
<h2>Hola Moto!</h2>
<div class="container-fluid">
<div class="row">
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-4">
<mvc-fbsearch-query-form></mvc-fbsearch-query-form>
<!--<fbsearch-query-form></fbsearch-query-form>-->
</div>
<div class="col-lg-8 col-md-8 col-sm-12 col-xs-12">
<mvc-fbsearch-results-list></mvc-fbsearch-results-list>
<!--<fbsearch-results-list ></fbsearch-results-list>-->
</div>
</div>
</div>
`
,
styleUrls: ['./fbsearch-index.component.css']
})
export class MVCFBSearchIndexComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}