首页 > 解决方案 > 使用 Angular8 和 Bootstrap4 将 Ng-bootstrap 表绑定到选择

问题描述

我一直试图让这项工作比我愿意承认的时间更长。Stackoverflow 上的许多示例与我正在尝试做的事情很接近,但似乎没有一个可以准确回答我的问题,所以我在问我自己的问题。我对 Angular 开发相当陌生。这是我正在尝试做的事情:

我正在尝试在具有分页、列排序和文本搜索的精美 bootstrap 4 表中显示数据。我希望表中显示的数据取决于下拉列表中选择的内容(最终它将取决于 2 个下拉列表,但出于此问题的目的,我正在简化示例)。填充选择列表和表格的数据应该来自服务。

我构建了一个Stackblitz来演示我正在尝试做的事情,但不知道如何将其连接起来。任何帮助将不胜感激!

标签: angularbootstrap-4angular8ng-bootstrap

解决方案


为此:

  • 每次在人员组件中选择/更改人员时,您都需要将其传递给表格组件
  • 根据选择和通过的人过滤国家[这里没有足够的信息为您执行此操作]
  • 使用您现有的 stackblitz,进行以下更改以实现上面的第一个项目符号

更改后,person.component.html

<form>
  <div class="form-group form-inline">
    <select name="person" id="person" (change)='someFunc($event)' [(ngModel)]="selectedOption" >
      <option *ngFor="let user of users" [value]="user.userid" class ="blueText"

      >{{ user.name }}</option>
    </select>
    selected user: {{selectedUser}}
  </div>
</form>

更改后,person.component.ts

import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { PersonService } from './person.service';
import { User } from './user.ts';
import { ChangeAssigneeService } from './change-assignee.service';

@Component({
  selector: 'person',
  templateUrl: './person.component.html',
  styleUrls: ['./person.component.scss']
})
export class PersonComponent implements OnInit {

  users: User[];
  selectedUser:any;
 @Output() private personSelected = new EventEmitter<number>();


  constructor(private personService: PersonService, private changeassigneeService: ChangeAssigneeService) { 
    this.selectedUser = '';
  }

  ngOnInit() {
    this.users = this.personService.getAssignees();
  }

someFunc(event){
  this.personSelected.emit(event.target.value);
  this.selectedUser = event.target.value;
}

  changeAssignee(val:any){
    this.changeassigneeService.sendAssignee(val);
    console.log("test");
  }

}

更改后,table-complete.html

<form>
  <person (personSelected)="onpersonSelected($event)"></person>
  we got <mark>{{personFromChild || 'nothing'}}</mark> from the table component
  <div class="form-group form-inline">
      Full text search: <input class="form-control ml-2" type="text" name="searchTerm" [(ngModel)]="service.searchTerm"/>
      <span class="ml-3" *ngIf="service.loading$ | async">Loading...</span>
  </div>

  <table class="table table-striped">
    <thead>
    <tr>
      <th scope="col">#</th>
      <th scope="col" sortable="name" (sort)="onSort($event)">Country</th>
      <th scope="col" sortable="area" (sort)="onSort($event)">Area</th>
      <th scope="col" sortable="population" (sort)="onSort($event)">Population</th>
    </tr>
    </thead>
    <tbody>
    <tr *ngFor="let country of countries$ | async">
      <th scope="row">{{ country.id }}</th>
      <td>
        <img [src]="'https://upload.wikimedia.org/wikipedia/commons/' + country.flag" class="mr-2" style="width: 20px">
        <ngb-highlight [result]="country.name" [term]="service.searchTerm"></ngb-highlight>
      </td>
      <td><ngb-highlight [result]="country.area | number" [term]="service.searchTerm"></ngb-highlight></td>
      <td><ngb-highlight [result]="country.population | number" [term]="service.searchTerm"></ngb-highlight></td>
    </tr>
    </tbody>
  </table>

  <div class="d-flex justify-content-between p-2">
    <ngb-pagination
      [collectionSize]="total$ | async" [(page)]="service.page" [pageSize]="service.pageSize">
    </ngb-pagination>

    <select class="custom-select" style="width: auto" name="pageSize" [(ngModel)]="service.pageSize">
      <option [ngValue]="2">2 items per page</option>
      <option [ngValue]="4">4 items per page</option>
      <option [ngValue]="6">6 items per page</option>
    </select>
  </div>

</form>

更改后,table-complete.ts

import {DecimalPipe} from '@angular/common';
import {Component, QueryList, ViewChildren, OnInit} from '@angular/core';
import {Observable} from 'rxjs';
import { User } from './user.ts';

import {Country} from './country';
import {CountryService} from './country.service';
import {NgbdSortableHeader, SortEvent} from './sortable.directive';
import { ChangeAssigneeService } from './change-assignee.service';


@Component(
    {selector: 'ngbd-table-complete', 
    templateUrl: './table-complete.html', 
    providers: [CountryService, DecimalPipe]})
export class NgbdTableComplete implements OnInit {
  countries$: Observable<Country[]>;
  total$: Observable<number>;
  personFromChild:any;

  //userId$: Observable<string>;
  userId$: string;

  @ViewChildren(NgbdSortableHeader) headers: QueryList<NgbdSortableHeader>;

  constructor(public service: CountryService, private changeassigneeService: ChangeAssigneeService) {
    this.countries$ = service.countries$;
    this.total$ = service.total$;
  }

  public onpersonSelected(personPassed: number) {
    this.personFromChild = personPassed;
    /* INSERT the logic to select countries based on this selected value */
  }


  ngOnInit(){
    this.changeassigneeService.changeAssignee$.subscribe(message => {
      this.userId$ = message;
      console.log(message);
    });
  }

  onSort({column, direction}: SortEvent) {
    // resetting other headers
    this.headers.forEach(header => {
      if (header.sortable !== column) {
        header.direction = '';
      }
    });

    this.service.sortColumn = column;
    this.service.sortDirection = direction;
  }
}

推荐阅读