You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在environment.ts配置文件中为DevExpress dxFilterBuilder添加基于API服务引用的动态过滤预设

解决方案:在environment.ts中配置动态过滤预设(结合DevExtreme dxFilterBuilder)

我来帮你搞定这个需求,结合你的场景(动态加载API数据、权限控制、环境配置解耦),咱们分步骤实现:

1. 更新environment.ts:存储过滤预设的元数据

首先,我们不在环境文件里直接存服务实例(会导致耦合和启动时加载问题),而是存过滤字段的元数据,包括数据源的获取标识(用标识解耦,避免直接依赖业务服务)。

修改后的environment.ts:

export const environment = {
  productName: 'test',
  production: false,
  // 新增过滤预设配置
  filterPresets: {
    // 为员工过滤场景定义预设
    employeeFilter: {
      fields: [
        {
          dataField: 'employeeId',
          caption: '员工',
          dataType: 'number',
          lookup: {
            // 用字符串标识后续要调用的数据提供者
            dataProviderKey: 'employeeListProvider'
          }
        },
        // 可添加其他自定义过滤字段...
      ]
    }
  }
};

2. 创建员工数据服务:封装API请求

写一个负责获取员工列表的服务,后端接口要配合校验用户登录状态和权限:

// src/app/services/employee.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

// 定义员工数据结构
export interface Employee {
  id: number;
  name: string;
}

@Injectable({ providedIn: 'root' })
export class EmployeeService {
  constructor(private http: HttpClient) {}

  // 获取员工列表的API请求(后端需校验权限)
  getEmployees(): Observable<Employee[]> {
    return this.http.get<Employee[]>('/api/employees');
  }
}

3. 注册数据提供者:解耦环境配置与业务服务

为了让环境配置里的dataProviderKey能对应到实际的服务方法,我们用Angular的依赖注入令牌来注册数据提供者:

// src/app/providers/filter-data-providers.ts
import { InjectionToken } from '@angular/core';
import { Observable } from 'rxjs';

// 定义数据提供者的类型
export type FilterDataProvider = () => Observable<any[]>;

// 注册员工列表的提供者令牌(与environment里的key对应)
export const EMPLOYEE_LIST_PROVIDER = new InjectionToken<FilterDataProvider>(
  'employeeListProvider'
);

然后在AppModule里配置提供者:

// src/app/app.module.ts
import { EMPLOYEE_LIST_PROVIDER } from './providers/filter-data-providers';
import { EmployeeService } from './services/employee.service';

@NgModule({
  providers: [
    {
      provide: EMPLOYEE_LIST_PROVIDER,
      // 用工厂函数封装服务方法,避免直接暴露服务
      useFactory: (employeeService: EmployeeService) => 
        () => employeeService.getEmployees(),
      deps: [EmployeeService] // 依赖注入EmployeeService
    }
  ]
})
export class AppModule {}

4. 在过滤组件中加载配置与数据(带权限校验)

最后,在dxFilterBuilder所在的组件里,先校验用户权限,再从环境配置加载预设,最后通过令牌获取数据提供者加载员工列表:

// src/app/components/filter/filter.component.ts
import { Component, OnInit, Injector } from '@angular/core';
import { environment } from '../../../environments/environment';
import { AuthService } from '../../services/auth.service'; // 你的权限服务
import { FilterDataProvider } from '../../providers/filter-data-providers';

@Component({
  selector: 'app-filter',
  templateUrl: './filter.component.html'
})
export class FilterComponent implements OnInit {
  filterFields: any[] = [];
  hasAccess = false;

  constructor(
    private authService: AuthService,
    private injector: Injector // 用Injector获取注册的提供者
  ) {}

  ngOnInit(): void {
    // 第一步:校验用户是否有访问过滤页面的权限
    this.hasAccess = this.authService.hasPermission('access-filter-page');
    
    if (this.hasAccess) {
      // 第二步:从环境配置获取员工过滤预设
      const presetFields = environment.filterPresets.employeeFilter.fields;
      // 第三步:加载动态数据源
      this.loadDynamicDataSources(presetFields);
    }
  }

  private loadDynamicDataSources(fields: any[]): void {
    // 遍历所有字段,处理需要动态加载数据的lookup字段
    fields.forEach(field => {
      if (field.lookup?.dataProviderKey) {
        // 通过Injector获取对应的数据源提供者
        const dataProvider = this.injector.get<FilterDataProvider>(
          field.lookup.dataProviderKey
        );
        
        // 调用提供者获取数据,赋值给lookup的dataSource
        dataProvider().subscribe(data => {
          field.lookup.dataSource = data;
          // 更新过滤字段数组,触发组件刷新
          this.filterFields = [...fields];
        });
      }
    });

    // 处理不需要动态数据的字段
    if (!this.filterFields.length) {
      this.filterFields = [...fields];
    }
  }
}

对应的组件模板:

<!-- src/app/components/filter/filter.component.html -->
<!-- 只有有权限的用户才能看到过滤组件 -->
<dx-filter-builder *ngIf="hasAccess" [fields]="filterFields"></dx-filter-builder>

关键注意点

  • 权限控制:组件初始化时先校验权限,只有通过校验才会触发API请求,完全符合你"不能在应用启动前加载数据"的要求。
  • 解耦设计:用依赖注入令牌代替直接在environment里引用服务,避免环境文件和业务逻辑耦合,便于后续扩展其他过滤预设。
  • 动态加载:数据只有在用户进入过滤页面且有权限时才会加载,不会在应用启动时提前请求API。

内容的提问来源于stack exchange,提问作者Konstantin Schütte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 03:32:42