使用Knockout.js实现MVVM模式

在现代Web开发中,MVVM(Model-View-ViewModel)模式是一种非常流行的架构模式,它帮助开发者创建丰富、响应式的显示和编辑用户界面,同时保持清晰的数据模型。用户不需要担心将数据模型绑定到视图上,因为任何时候数据发生变化,视图都会自动刷新。

在进行一个项目时,被要求创建一个多选框。考虑到正在使用Knockout.js,想到了创建一个自定义绑定处理器,以便可以重复使用代码。

以下是HTML代码:

<select id="customID" data-bind="Values: ViewModelPropertyName"> <option value="1">value1</option> <option value="2">value2</option> <option value="3">value3</option> <option value="4">value4</option> </select> <img id="imgcustomID" src="../add.png"/><br/> <ul id="ulcustomID" class="navlist"></ul>

以下是CSS样式:

.navlist { margin-left: 0; padding-left: 0; list-style: none; } .navlist li { padding-left: 25px; background-image: url(../images/minus.png); background-repeat: no-repeat; background-position: 0 .1em; height: 16px; }

以下是JavaScript代码:

<script type="text/javascript"> ko.bindingHandlers.Values = { init: function (element, valueAccessor) { var _this = ko.bindingHandlers.Values; var id = jQuery(element).attr('id'); jQuery(element).after("<img src='../../../images/add.png' id='img" + id + "' onClick='javascript: ko.bindingHandlers.Values.setCommand(\"" + id.toString() + "\");'></img><ul class='navlist' id='ul" + id + "'></ul>"); var values = new Array(); var value = ko.utils.unwrapObservable(valueAccessor()); if (value) { values[0] = value; if (values[0] == "") values.splice(0, 1); setTimeout("ko.bindingHandlers.Values.addLI('" + id + "','" + values + "',0);", 300); } }, setCommand: function (id) { var _this = ko.bindingHandlers.Values; if (jQuery('#' + id).attr('value') !== "") { var select = document.getElementById(id); if (select.selectedIndex >= 0) _this.addLI(id, select.options[select.selectedIndex].value, 1); } }, addLI: function (id, values, mode) { var _this = ko.bindingHandlers.Values; var currentvalues = []; var prop = id.replace("slct", ""); var viewModelData = JSON.parse(ko.toJSON(viewModel)); if (viewModelData[prop]) { if (viewModelData[prop].toString().search(",") !== -1) { var currentvalues = eval("viewModel." + prop + "().split(',')"); } else { currentvalues[0] = eval("viewModel." + prop + "()"); } if (currentvalues[0] == "") currentvalues.splice(0, 1); if (values !== "" && mode == 1) currentvalues.pushIfNotExist(values); eval("viewModel." + prop + "('" + currentvalues.join(',') + "')"); } else { eval("viewModel." + prop + "(" + values + ")"); } if (mode == 0) { jQuery.each(currentvalues, function (key, value) { var li = document.createElement('li'); var select = document.getElementById(id); li.innerHTML = _this.getText(id, value.trim()); li.customValue = value; var ul = document.getElementById('ul' + id); li.onclick = function () { var option = document.createElement('option'); option.text = this.innerHTML; option.value = this.customValue; select.add(option); ul.removeChild(li); eval("viewModel." + prop + "(_this.getValues('" + id + "'))"); }; ul.appendChild(li); _this.removeOption(id, value.trim()); }); } else { var li = document.createElement('li'); var select = document.getElementById(id); li.innerHTML = _this.getText(id, values); li.customValue = values; var ul = document.getElementById('ul' + id); li.onclick = function () { var option = document.createElement('option'); option.text = this.innerHTML; option.value = this.customValue; select.add(option); ul.removeChild(li); eval("viewModel." + prop + "(_this.getValues('" + id + "'))"); }; ul.appendChild(li); _this.removeOption(id, values); } }, getValues: function (id) { return jQuery('#ul' + id + ' li').map(function () { return jQuery(this).attr('customValue'); }).get().join(", "); }, getText: function (id, value) { return jQuery("#" + id + " option[value='" + value + "']").text(); }, removeOption: function (id, value) { jQuery("#" + id + " option[value='" + value + "']").remove(); } }; var viewModel = {}; viewModel.ViewModelPropertyName = '1,2'; ko.applyBindings(viewModel); </script>

请确保将add.png和minus.png图片添加到images文件夹中,并确保它们可以从CSS和HTML文件中访问。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485