我刚刚开始尝试使用 JavaScript、JQuery 和 Knockout.js(我通常在 Java 中的服务器端工作)并且它非常出色 - 但是我已经碰壁了,我非常怀疑我正在做,无论我想做什么,“按书本”。
我在这里为它创建了一个小提琴:http: //jsfiddle.net/kcyhw/
我的使命:
- 我需要创建一个可以在整个网站上重复使用的模板。外汇。一个包含创建、编辑和删除用户的可能性的模板——这将使在“用户配置”窗口中创建用户变得容易,或者作为向导的一部分。无论哪种方式,控制一切的逻辑都应该是相同的。然而,除了为数据共享同一个arrayObservable之外,选择选项当然不应该互相观察。现在,它完全是一个选择框。我正在使用 JQuery.serialize 将整个表单转换为键值,以发送到服务器,因此重要的是我不仅要获取值,还要将其“保存”在选择框的 value 属性中.
我的问题:
- 我根本无法弄清楚 Knockout.js 和选择框是如何连接的。在选择框和属性部分中,所有对象都通过它们各自的值(id 和全名)很好地显示。使用 jQuery 进行序列化时,它只会打印:“perselect="... 所以它没有得到值。
我尝试了以下方法:
在数据绑定中使用 optionValue - 它可以工作,并且绑定到“值”,但是,我可以看到它“接管”了我的绑定,并杀死了我从对象中检索到的文本。我删除了它,然后继续...
计算值,但是它没有解决,因为模板需要(据我所知)一个文字对象,并且函数不能引用此类对象中的其他属性。
创建了我自己的绑定,因此我可以获得对元素(选择框)和所有其他绑定值的引用。在这个函数中,我尝试使用 jQuery 在传入的元素上设置属性“值”,但是它不起作用。我还可以看到,绑定被调用了 4 次(这可能是因为它调用了 init 然后为我创建的每个包含选择框的模板进行更新)。
对我来说,看起来我已经创造了一个该死的混乱,如果一些聪明的人能指出我如何解决这个问题的正确方向,我将不胜感激。资源、代码片段、建议……无论你得到什么。
编码:
<html>
<head>
<script src="javascript/jquery-1.10.2/jquery-1.10.2.js"></script>
<script src="javascript/knockout-2.3.0/knockout-2.3.0.js"></script>
<script src="javascript/knockout.mapping-master-2.0/knockout.mapping-latest.js"></script>
<script type="text/javascript" src="javascript/json2-2.0/json2.js"></script>
<title>A Knockout Demo</title>
<script>
/**
* JQuery Function
*/
$(document).ready(function() {
// Domain Object
var Person = function(id, fullname) {
var self = this;
self.id = id;
self.fullname = fullname;
};
// Knockout Model
var KoModel = function() {
var self = this;
// Declare observables
self.persons = ko.observableArray();
// Allows observables to share an array without observing each other
self.createPersonSelector = function(namevalue) {
var person = new Object();
person.selectedPerson = ko.observable();
person.name = namevalue;
return person;
}
// Prints a serialized string which could be sent to the server
self.printFormElements = function(formElements) {
alert($(formElements).serialize());
}
// Will change the person select value, to a real value
self.changePersonSelectValue = function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var value = valueAccessor(), allBindings = allBindingsAccessor();
// Next, whether or not the supplied model property is observable, get its current value
var valueUnwrapped = ko.unwrap(value);
// Now manipulate the DOM element
var $eleme = $(element);
if ($eleme == null) {
return;
}
// Change to item number two in the list *doesn't work*.
$eleme.val(2);
};
// Person selectbox value binding
ko.bindingHandlers.personSelect = {
init : function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
self.changePersonSelectValue(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
},
update : function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
self.changePersonSelectValue(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
}
};
// Put some test-data into the array
self.persons.push(new Person(1, 'Martin Smith'));
self.persons.push(new Person(2, 'Andy Gregersen'));
self.persons.push(new Person(3, 'Thomas Peep'));
};
// Apply bindings
ko.applyBindings(new KoModel());
});
</script>
<script type="text/html" id="person-template">
<span>Choose ID: </span><select data-bind="options: $root.persons, optionsText: 'id', personSelect: true, value:selectedPerson, attr: {'name': name, 'id': name}"></select></br>
<span>ID:</span> <span data-bind="text: selectedPerson().id"></span></br>
<span>Full Name: </span> <span data-bind="text: selectedPerson().fullname"></span></br>
</script>
<body>
<h1>Person Select One</h1>
<form data-bind="submit: printFormElements">
<div
data-bind="template: { name: 'person-template', data:createPersonSelector('personselect')}"></div>
<button type="submit">Submit</button>
</br>
</form>
<h1>Person Select Two</h1>
<form data-bind="submit: printFormElements">
<div
data-bind="template: { name: 'person-template', data:createPersonSelector('personselecttwo')}"></div>
<button type="submit">Submit</button>
</br>
</form>
</body>
</html>