gpt4 book ai didi

javascript - Knockoutjs 模板 : How to use 1 object array for 2 DOM elements after filtering that array by some property?

转载 作者:行者123 更新时间:2023-12-01 05:32:48 25 4
gpt4 key购买 nike

我有一个模板和一个名为“employees”的“bindingHandler”以及一个员工数组。

我想在两个不同的元素中使用相同的员工对象数组(用于模板),但每个元素都有不同的数组数据。

例如:我有一组员工(我从服务器获得),如下所示:

var employees = [
{ FirstName: 'John', LastName: 'John', JobTitleCode: 101 },
{ FirstName: 'Guest', LastName: 'Guest', JobTitleCode: 15 },
{ FirstName: 'David', LastName: 'David', JobTitleCode: 300 },
{ FirstName: 'Ryan', LastName: 'Ryan', JobTitleCode: 300 },
{ FirstName: 'Alex', LastName: 'Alex', JobTitleCode: 10 },
{ FirstName: 'Michael', LastName: 'Michael', JobTitleCode: 101 }
];

我的 HTML 是这样的:

<div>
<b>Job title code 101</b>
<div data-bind="employees: { employeesModel: Employees, jobTitleCode: 101 }" />
</div>

<br/>

<div>
<b>Job title code 300</b>
<div data-bind="employees: { employeesModel: Employees, jobTitleCode: 300 }" />
</div>

我需要所有在第一个 div 元素上具有 JobTitleCode 101 的员工以及在第二个 div 元素上具有 JobTitleCode 300 的员工。

这是我的模板和绑定(bind)处理程序:

(function () {

ko.employeeModel = function (config) {
var self = this;
self.Exclude = config.exclude || [];
self.AllEmployees = config.employees;

self.Employees = ko.pureComputed(function () {
return ko.utils.arrayFilter(self.AllEmployees, function (employee) {
return $.inArray(employee.JobTitleCode, self.Exclude) == -1;
});
});
};

var templateEngine = new ko.nativeTemplateEngine();

templateEngine.addTemplate = function (templateName, templateMarkup) {
document.write("<script type='text/html' id='" + templateName + "'>" + templateMarkup + "</script>");
};

templateEngine.addTemplate("ko_employees", "\
<div data-bind=\"foreach: Employees\">\
<div>\
<label data-bind=\"text: FirstName\"></label>\
<label data-bind=\"text: LastName\"></label>\
<label data-bind=\"text: JobTitleCode\"></label>\
</div>\
</div>");

ko.bindingHandlers.employees = {
init: function () {
return { 'controlsDescendantBindings': true };
},

update: function (element, valueAccessor, allBindings) {
var accessor = valueAccessor();
var viewModel = accessor.employeesModel ? accessor.employeesModel : accessor;
var jobTitleCode = accessor.jobTitleCode ? accessor.jobTitleCode : 0;

while (element.firstChild) {
ko.removeNode(element.firstChild);
}

var attachmentsTemplateName = "ko_employees"

var employeesContainer = element.appendChild(document.createElement("div"));
ko.renderTemplate(attachmentsTemplateName, viewModel, { templateEngine: templateEngine }, employeesContainer, "replaceNode");
}
};
})();

最后是 View 模型:

var vm = function (employeeArr) {
var self = this;
self.Employees = new ko.employeeModel({
exclude: [10, 15],
employees: employeeArr
});
}

// data from server
var employees = [
{ FirstName: 'John', LastName: 'John', JobTitleCode: 101 },
{ FirstName: 'Guest', LastName: 'Guest', JobTitleCode: 15 },
{ FirstName: 'David', LastName: 'David', JobTitleCode: 300 },
{ FirstName: 'Ryan', LastName: 'Ryan', JobTitleCode: 300 },
{ FirstName: 'Alex', LastName: 'Alex', JobTitleCode: 10 },
{ FirstName: 'Michael', LastName: 'Michael', JobTitleCode: 101 }
];

var emloyeeVm = new vm(employees);
ko.applyBindings(emloyeeVm);

谢谢!

最佳答案

自定义绑定(bind)处理程序不是满足您的要求的正确工具恕我直言。自定义绑定(bind)处理程序用于处理特殊的 DOM 交互,例如创建弹出组件或日期选择器。您正在重新发明 foreach 绑定(bind),并在其中执行 View 模型逻辑。

这是另一种方法。关键是使用计算可观察量来获取单独的列表:

var vm = function (employeeArr) {
var self = this;
var exclude = [10, 15];

self.employees = ko.observableArray(employeeArr);

self.groups = ko.computed(function() {
var groups = [], result = [];
self.employees().forEach(function(e) {
if (exclude.indexOf(e.JobTitleCode) < 0) {
if (!groups.hasOwnProperty(e.JobTitleCode)) {
groups[e.JobTitleCode] = { key: e.JobTitleCode, people: [] };
result.push(groups[e.JobTitleCode]);
}
groups[e.JobTitleCode].people.push(e);
}
});
return result;
});
}

// data from server
var employees = [
{ FirstName: 'John', LastName: 'John', JobTitleCode: 101 },
{ FirstName: 'Guest', LastName: 'Guest', JobTitleCode: 15 },
{ FirstName: 'David', LastName: 'David', JobTitleCode: 300 },
{ FirstName: 'Ryan', LastName: 'Ryan', JobTitleCode: 300 },
{ FirstName: 'Alex', LastName: 'Alex', JobTitleCode: 10 },
{ FirstName: 'Michael', LastName: 'Michael', JobTitleCode: 101 }
];

var emloyeeVm = new vm(employees);
ko.applyBindings(emloyeeVm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>

<script type="text/html" id="group101">
<b data-bind="text: key"></b>
<div data-bind="foreach: people">
<div>
<span data-bind="text: FirstName"></span>
<span data-bind="text: LastName"></span>
</div>
</div>
</script>

<script type="text/html" id="group300">
<b data-bind="text: key"></b>
<ul data-bind="foreach: people">
<li>
<span data-bind="text: FirstName"></span>
<span data-bind="text: LastName"></span>
</li>
</ul>
</script>

<!-- ko foreach: groups -->
<hr>
<div data-bind="template: 'group' + key"></div>
<!-- /ko -->

关于javascript - Knockoutjs 模板 : How to use 1 object array for 2 DOM elements after filtering that array by some property?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36068745/

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