首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >特定性质的KnockoutJS滤波器

特定性质的KnockoutJS滤波器
EN

Stack Overflow用户
提问于 2019-01-03 14:35:35
回答 1查看 95关注 0票数 0

我使用JS中的getJSON-方法为作业应用程序网站使用KnockoutJS。

不幸的是,我得到了这样的结构:

  • 办事处
代码语言:javascript
运行
复制
- new york
代码语言:javascript
运行
复制
    - departments  
        - finance  
            - jobs  
            - example
            - ...

代码语言:javascript
运行
复制
        - IT
        - logistics
        - marketing

代码语言:javascript
运行
复制
- washington
代码语言:javascript
运行
复制
    - departments  
        - finance
        - IT
        - logistics
        - marketing

代码语言:javascript
运行
复制
- los angeles
代码语言:javascript
运行
复制
    - departments  
        - finance
        - IT
        - logistics
        - marketing

我使用JS中的filter-function过滤掉了一些尚未开放的城市办公室,效果很好。

,但现在我需要过滤除物流以外的所有部门,因为我只想显示特定城市的物流工作。我希望它是动态的,所以它只会显示物流,即使有更多的部门来。

我找不到一个很好的解决办法。有什么想法吗?

编辑:这里是假JSON:

EN

回答 1

Stack Overflow用户

发布于 2019-01-05 07:39:37

由于您对作业感兴趣,我建议创建一个Job模型,将当前仅由结构定义的数据合并到一个方便的对象中。

要使数据扁平化,可以执行一组reduce操作:

代码语言:javascript
运行
复制
const jobData={offices:[{location:"ny",departments:[{name:"Logistics",jobs:[{title:"driver for x"},{title:"driver for y"}]},{name:"Finance",jobs:[{title:"CFO"}]}]},{location:"la",departments:[{name:"Logistics",jobs:[{title:"driver for z"}]},{name:"IT",jobs:[{title:"tech support manager"}]}]}]}


const Job = (title, department, officeLocation) => ({
  title,
  department,
  officeLocation
});

const JobList = ({ offices }) => ({
  jobs: offices.reduce(
    (allJobs, { location, departments }) => departments.reduce(
      (allJobs, { name, jobs }) => jobs.reduce(
        (allJobs, { title }) => allJobs.concat(
          Job(title, name, location)
        ),
        allJobs
      ),
      allJobs
    ),
    []
  )
})

console.log(JobList(jobData))

现在我们已经整理好了数据格式,我们可以开始编写剔除代码了。

我创建了一个table来呈现一个计算出来的作业列表。在计算中,我们对两个属性进行了过滤:所需的办公室和所需的部门。

过滤器本身是“平面的”,因为Job对象拥有我们需要的所有数据。例如,物流过滤器可以应用如下:

代码语言:javascript
运行
复制
const logisticsJobs = ko.pureComputed(
  jobList().filter(job => job.department === "logistics")
);

下面是一个例子。使用表头中的<select>元素应用筛选器。

代码语言:javascript
运行
复制
function JobFinder() {
  const jobData = ko.observable({ offices: [] });
  const jobList = ko.pureComputed(
    () => JobList(jobData())
  );
  
  // Lists of properties we can filter on
  this.offices = ko.pureComputed(
    () => uniques(jobList().map(job => job.officeLocation))
  );
  
  this.departments = ko.pureComputed(
    () => uniques(jobList().map(job => job.department))
  );
  
  // Filter values
  this.requiredOffice = ko.observable(null);
  this.requiredDepartment = ko.observable(null);
  
  // Actual filter logic
  const officeFilter = ko.pureComputed(
    () => this.requiredOffice()
      ? job => job.officeLocation === this.requiredOffice()
      : () => true
  );
  
  const departmentFilter = ko.pureComputed(
    () => this.requiredDepartment()
      ? job => job.department === this.requiredDepartment()
      : () => true
  );
  
  const allFilters = ko.pureComputed(
    () => [ officeFilter(), departmentFilter() ]
  )
  
  const filterFn = ko.pureComputed(
    () => job => allFilters().every(f => f(job))
  )
  
  // The resulting list
  this.filteredJobs = ko.pureComputed(
    () => jobList().filter(filterFn())
  );

  // To load the data (can be async in real app)
  this.loadJobData = function() {
    jobData(getJobData());
  }
};

// Initialize app
const app = new JobFinder();
ko.applyBindings(app);
app.loadJobData();


// utils
function uniques(xs) { return Array.from(new Set(xs)); }


// Code writen in the previous snippet:
function getJobData() { 
  return {offices:[{location:"ny",departments:[{name:"Logistics",jobs:[{title:"driver for x"},{title:"driver for y"}]},{name:"Finance",jobs:[{title:"CFO"}]}]},{location:"la",departments:[{name:"Logistics",jobs:[{title:"driver for z"}]},{name:"IT",jobs:[{title:"tech support manager"}]}]}]};
};


function Job(title, department, officeLocation) {
  return {
    title,
    department,
    officeLocation
  }
};

function JobList({ offices }) {
  return offices.reduce(
    (allJobs, { location, departments }) => departments.reduce(
      (allJobs, { name, jobs }) => jobs.reduce(
        (allJobs, { title }) => allJobs.concat(
          Job(title, name, location)
        ),
        allJobs
      ),
      allJobs
    ),
    []
  )
};
代码语言:javascript
运行
复制
th { 
  text-align: left;
  width: 30% 
};
代码语言:javascript
运行
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<table>
  <thead>
    <tr>
      <th>Job Title</th>
      <th>Location</th>
      <th>Department</th>
    </tr>
    <tr>
      <th></th>
      <th>
        <select data-bind="
          options: offices,
          value: requiredOffice,
          optionsCaption: 'Show all locations'">
        </select>
      </th>
        <th>
        <select data-bind="
          options: departments,
          value: requiredDepartment,
          optionsCaption: 'Show all departments'">
        </select>
      </th>
    </tr>
  </thead>
  <tbody data-bind="foreach: filteredJobs">
    <tr>
      <td data-bind="text: title"></td>
      <td data-bind="text: officeLocation"></td>
      <td data-bind="text: department"></td>
    </tr>
  </tbody>
</table>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54024386

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档