gpt4 book ai didi

javascript - KnockoutJS 按特定属性过滤

转载 作者:行者123 更新时间:2023-12-03 00:27:26 26 4
gpt4 key购买 nike

我使用 KnockoutJS 来创建工作申请网站,并使用 JS 中的 getJSON 方法。

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

  • 办公室

    • 纽约

      • 部门
        • 金融
          • 职位
            • 示例
            • ...
        • IT
        • 物流
        • 营销
    • 华盛顿

      • 部门
        • 财务
        • IT
        • 物流
        • 营销
    • 洛杉矶

      • 部门
        • 财务
        • IT
        • 物流
        • 营销

我使用JS中的filter函数过滤掉了一些尚未开放的城市的办事处,效果很好。

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

我找不到好的解决方案。有什么想法吗?

编辑:这是虚拟 JSON:

enter image description here

最佳答案

既然你对工作感兴趣,我建议做一个Job模型将当前仅由结构定义的数据合并到一个方便的对象中。

为了展平数据,您执行一组 reduce行动:

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))

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

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

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

const logisticsJobs = ko.pureComputed(
jobList().filter(job => job.department === "logistics")
);

这是示例。使用<select>表头中的元素以应用过滤器。

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
),
[]
)
};
th { 
text-align: left;
width: 30%
};
<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>

关于javascript - KnockoutJS 按特定属性过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54024386/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com