为 KnockOut.js 创建自定义(值)绑定处理程序





0/5 (0投票)
如果你长期从事 Web 开发,你一定听说过 knockout.js。它在 JavaScript 中实现了 MVVM 模式。Silverlight 的开发人员
如果你长期从事 Web 开发,你一定听说过 knockout.js。它在 JavaScript 中实现了 MVVM 模式。Silverlight 的开发人员一定对这个词很熟悉。 这有助于创建具有清晰底层数据模型的丰富、响应式的显示和编辑器用户界面。用户无需担心将数据模型绑定到你的视图。 任何时候,你的数据发生更改,你的视图都会自动刷新。
在进行一个项目时,我被要求创建一个多选框。因为我正在使用它,所以我考虑创建自定义绑定处理程序,以便我可以一次又一次地使用我的代码。
以下是 HTML
1) 拥有如下的 select 元素
<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>
2) 在你的 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;
}
3) 在你的 HTML 文件中添加以下 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>
4) 将两个图像 add.png 和 minus.png 放入你的 images 文件夹中,并确保可以从你的 CSS 和 HTML 文件中访问它们。
希望这对那些想在他们的项目中使用 knockout.js 的人来说非常有用。 要使用上面的代码,请不要忘记添加最新的 jQuery 库和 knockout.js
编码愉快 :)