Knockoutjs模板:通过某些属性过滤数组后,如何将1个对象数组用于2个DOM元素?

麦可

我有一个模板,一个名为“ employees”的“ bindingHandler”和一个“雇员数组”。

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

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

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的员工。

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

(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");
		}
	};
})();

最后是viewmodel:

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

谢谢!

耶罗恩

自定义绑定处理程序不是您所需的恕我直言的正确工具。自定义绑定处理程序旨在处理特殊的DOM交互,例如,创建弹出组件或日期选择器。您正在重新创建foreach绑定,并在其中进行视图模型逻辑。

这是一个替代方法。关键是使用computed可观察对象获得单独的列表:

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何将数组转换为ARM模板中一个对象的属性?

如何使用lodash通过单个属性过滤/比较2个对象数组?

如何通过元素属性值过滤对象数组并使用jq选择第一个元素?

得到了一个由2个对象组成的数组。每个对象都有一个属性`events`,其中包含一个对象数组。如何过滤PartitionId不为1的元素?

如何将具有 n 个元素的 2 个数组合并为具有 n 个对象的 1 个数组?

如何将2个数组组合成1个对象javascript

检查数组1中的特定条件后,如何将元素从一个数组(数组1)添加到另一个数组(数组2)?

如何将 javascript 对象转换为 1 个元素的数组?

如何将数组属性写入DOM元素数组

如何将数组转换为0或1个元素?

如何将2个元素放入数组的单行中?

如何将更新后的数组元素返回到DOM?

如何将2个数组数组组合到对象数组

在Coffeescript中,如何将一个对象的数组按一个属性分组?

如何将对象数组中的某些属性合并到另一个数组中?

如何将一个函数用于2个数组?

如何将向量化函数应用于numpy数组的上一个元素?

如何根据某些条件合并2个对象的嵌套数组属性?

当某些对象必须避免配对在一起时,如何将一个数组的元素随机映射到另一个数组的元素?

如何将数组的元素添加到另一个对象并计数

我如何将数组划分为子数组,每个子数组有 5 个元素,并将单独的类应用于每个子数组中的元素

如何将数组元素从一个对象匹配到另一个对象?

如何将一组对象(不同长度)转换为一个与原始数组中的元素具有不同属性的对象?

如何通过另一个对象数组过滤对象数组[ES6]

如何将“n”个对象转换为数组

如何将1个以上的属性绑定到元素?

如何将2个1d数组转换为一个1d数组,但两个值都应在一个元素内

Fortran,如何将2个数组合并(单元)到新的1个数组中,该数组包含先前数组中的唯一元素

如何将规则仅应用于数组中的某些元素