Angular service无法从给定URL取数据列然后传给component,望大侠们指点

发布于 2022-09-06 15:27:22 字数 1472 浏览 22 评论 0

项目要求从给定的URL取得数据,然后列到Dropdown组件的select list中。我尝试着从service中用HttpClient得到数据,并传给Component,结果怎么也不成功,请问到底哪里出问题了?各位给指点一下迷津吧。
主要代码如下:
//data.service.ts
......
@Injectable()
export class DataService {
private dataUrl = 'https://library.com/data.....';
private list: Library[];
......
constructor(private http: HttpClient) {}

public listData(pattern: string): Observable<Library[]> {

this.getList(this.dataUrl); 

return of(this.list
  .filter((library) => library.name.toUpperCase().indexOf(pattern.toUpperCase()) !== -1)
  .sort(this.sortFunction));

}

getList(urlStr: string) {

this.http
  .get(urlStr)
  .subscribe((data: Library[]) => {
    if (data) {
      this.list = data;
    } else {
      this.list = null;
    }
  });

}
......

}

//dropdown.component.ts
......
import {DataService} from '../../service/data.service';

@Component({
selector: 'app-dropdown',
templateUrl: './dropdown.component.html'
})
export class DropdownComponent implements OnInit {
public listItems: (item: string) => Observable<Library[]>;

ngOnInit() {
this.listItems = (term: string) => this.DataService.listData(term);
}
......
}

在Html中就是列出一个dropdown组件,下拉列表中就应该是取得的listItems。但问题是没有取得任何数据,下拉列表中是空的,点击任何一个都显示undefined。

谢谢啦先!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

知足的幸福 2022-09-13 15:27:22

因为listItems是异步拿到的,所以你在绑定dropdown数据源的时候,可以有两种方式:

  1. 绑定一个数组,在template里面可以这样绑定:
<dropdown [data]="listItems"></dropdown>

listItems: Library[];

getList(urlStr: string) : void {
  this.http
  .get(urlStr)
  .filter((data: Library[]) => data !== null)
  .subscribe((data: Library[]) => {
     this.listItems = data.filter((library) => library.name.toUpperCase().indexOf(pattern.toUpperCase()) !== -1)
  .sort(this.sortFunction))
  });
}
  1. 绑定一个Observable, 但在做绑定的时候需要加上async pipe。
<dropdown [data]="listItems | async"></dropdown>

listItems: Observable<Library[]>;

getList(urlStr: string) : Observable<Library[]> {
  this.http
  .get(urlStr)
  .filter((data: Library[]) => data !== null)
  .map((data: Library[]) => {
    return data.filter((library) => library.name.toUpperCase().indexOf(pattern.toUpperCase()) !== -1)
  .sort(this.sortFunction))
  });
}

this.listItems = getList("url");
李不 2022-09-13 15:27:22

谢谢@肾导的回答!出差刚回来,抱歉答谢迟了。
两种方法都试了一下,结果都不行(主要是本人技术实在太浅)。在filter处报错提示:Property 'filter' does not exist on type Observable<Object>. import {filter} from 'rxjs/operator/filter'; 也不行,把filter删除后虽未报错,但提取不到数据。
用下面两种方法试了下,显示listDropdownItems可以得到数据,但是却不能放到Dropdown的下拉列表里。不知道问题出在哪里?

//dropdown.component.ts
...
public getItems: (ids: string[]) => Observable<Library[]>;
public listItems: (item: string) => Observable<Library[]>;
public listItemsMax: (item: string, ids: string[]) => Observable<Library[]>;
public entityToSelectItem: (entity: Library) => SelectItem;
public count: number;

urlStr = 'https://.../api/dict/Library/...';
public listDropdownItems: Library[];
......

ngOnInit() {
this.dropdownService.getMembers(this.urlStr).subscribe((data: Library[]) => {

  if (data !== null) {
    this.listDropdownItems = data;
  } else {
    this.listDropdownItems = null;
  }
});

this.initDropdownItem();

}

private initDropdownItem() {

this.listItems = (term: string) => this.listData(term);
this.listItemsMax = (term: string, ids: string[]) => {
  const selectedCount = ids ? ids.length : 0;
  return this
    .listDataMax(term, 3 + selectedCount)
    .pipe(
      tap(response => this.count = response.count),
      map((response) => response.results)
    );
};
this.getItems = (ids: string[]) => this.getItemData(ids);
this.entityToSelectItem = (entity: any) => {
  return {
    id: entity.id,
    text: entity.libraryDisplay,
    entity: entity
  };
};

}

listData(pattern: string, maxResults?: number): Observable<Library[]> {

return of(this.listDropdownItems
  .filter((library) => library.libraryDisplay.toUpperCase().indexOf(pattern.toUpperCase()) !== -1)
  .sort(this.sortFunction));

}

sortFunction(library1: Library, library2: Library) {

if (library1.libraryDisplay < library2.libraryDisplay) {
  return -1;
}
if (library1.libraryDisplay > library2.libraryDisplay) {
  return 1;
}
return 0;

}

listDataMax(pattern: string, maxResults: number): Observable<{ count: number, results: Library[] }> {

const filteredList = this.listDropdownItems
  .filter((library) => library.libraryDisplay.toUpperCase().indexOf(pattern.toUpperCase()) !== -1)
  .sort(this.sortFunction);

return timer(200)
  .pipe(map((t) => {
    return {
      count: filteredList.length,
      results: maxResults && maxResults < filteredList.length ? filteredList.splice(0, maxResults) : filteredList
    };
  }));

}

getItemData(ids: string[]): Observable<Library[]> {

const selectedItems: Library[] = [];

ids.forEach((id) => {
  this.listDropdownItems
    .filter((item) => item.id === id)
    .map((item) => selectedItems.push(item));
});

return of(selectedItems);

}
.......

//dropdown.service.ts
import {HttpClient, HttpHeaders} from '@angular/common/http';

@Injectable()
export class DropdownService {
private headers: HttpHeaders = new HttpHeaders().set('Content-Type', 'application/json');
private options = {headers: this.headers};

constructor(private http: HttpClient) { }

getMembers(urlStr: string) {

return this.http
  .get(urlStr);

}

}

//dropdown.component.html
//下面数据都显示出来了。
<div>
<ul *ngIf="listDropdownItems">

<li *ngFor="let listDropdownItem of listDropdownItems;">
  <p>
    ID: <span>{{listDropdownItem.id}}</span>
    ModuleName: <span>{{listDropdownItem.modulename}}</span>
    LibraryDisplay: <span>{{listDropdownItem.libraryDisplay}}</span>
   </p>
</li>

</ul>
</div>
//但是下面的Dropdown下拉列表里显示不出来,是空的,点击下拉框没有任何反应。
<form [formGroup]="form">
<div class="form-group col-md-6">

    <h2>dropdown-select</h2>
    <app-dropdown cssStyle="form-control input-sm"
                         placeholder="Type to search..."
                         [dataProvider]="listItems"
                         [selectItemAdapter]="entityToSelectItem"
                         [selectedProvider]="getItems"></app-dropdown>
  </div>

</div>
</form>

但如果把listDropdownItems定义成固定的Library[]数组,而不是从Url取到的,如下,则上面的Dropdown下拉列表是没有问题的。
listDropdownItems: Library[] = [

{
id: '3',
  modulename: 'libraryApp',
  libraryDisplay: 'libraryApp'
}, {id: '4',
  modulename: 'Test',
  libraryDisplay: 'Test'}

];

请各位老师们再指教一下吧!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文