我最近开始使用淘汰赛。我试图在一个看似非传统方式的项目中使用它。我需要维护服务器端代码发出的DOM ID和结构。但是,我想利用knockout来促进客户端操作,方法是利用模式将页面上的字段作为javascript对象引用。
我有一个概念验证片段,但我想知道当我开始添加更多部分时它的扩展程度。我想得到一些反馈,看看更有经验的淘汰赛用户必须说些什么。
HTML
<!--
* We would then have a whole other section like fieldset0 after fieldset0 for a different people category
* We need to use the ids returned by the page, just add knockout on top without modifying DOM structure (except for sorting people based on sort order field, after removing item2 and adding again, it should go after item3 - if all 3 were on the page)
-->
<fieldset name="fieldset0" id="el_fieldset0">
<fieldset name="fieldset1" id="el_fieldset1">
<h1><span id="person1"></span></h1>
<input id="hasdata1" type="hidden" value="Yes" />
<label for="name1">name</label>
<input id="name1" value="andrew" />
<label for="age1">age</label>
<input id="age1" value="30" />
<label for="grade1">grade</label>
<select id="grade1">
<option selected>A</option>
<option>B</option>
<option>C</option>
<option>F</option>
</select> <a id="remove1" class="remove" href="javascript:void(0)">remove</a>
</fieldset>
<fieldset name="fieldset2" id="el_fieldset2">
<h1><span id="person2"></span></h1>
<input id="hasdata2" type="hidden" value="Yes" />
<label for="name2">name</label>
<input id="name2" value="brandon" />
<label for="age2">age</label>
<input id="age2" value="40" />
<label for="grade2">grade</label>
<select id="grade2">
<option>A</option>
<option selected>B</option>
<option>C</option>
</select> <a id="remove2" class="remove" href="javascript:void(0)">remove</a>
</fieldset>
<fieldset name="fieldset3" id="el_fieldset3">
<h1><span id="person3"></span></h1>
<input id="hasdata3" type="hidden" value="" />
<label for="name3">name</label>
<input id="name3" value="calvin" />
<label for="age3">age</label>
<input id="age3" value="50" />
<label for="grade3">grade</label>
<select id="grade3">
<option>A</option>
<option>B</option>
<option selected>C</option>
</select> <a id="remove3" class="remove" href="javascript:void(0)">remove</a>
</fieldset> <a id="addItem" class="add" href="javascript:void(0)">add</a>
</fieldset>
的Javascript
var myNamespace = {};
$(document).ready(function () {
//assign fieldset variables
myNamespace.$fieldset0 = $("#el_fieldset0"); // parent for all items
//individual items
myNamespace.$fieldset1 = $("#el_fieldset1");
myNamespace.$fieldset2 = $("#el_fieldset2");
myNamespace.$fieldset3 = $("#el_fieldset3");
//set the number of objects
myNamespace.personObjectCount = 3;
//set utilityArrays
myNamespace.personObjects = [];
myNamespace.availablePersonObject = [];
//assign data-bind attributes to html
for (var i = 0; i < myNamespace.personObjectCount; i++) {
var objectIndex = i + 1;
var currentFielsetStr = "$fieldset" + objectIndex;
//myNamespace[currentFielsetStr] = $("#el_fieldset"+ objectIndex);
myNamespace[currentFielsetStr].find("input[id^='name']").attr("data-bind", "value: personName");
myNamespace[currentFielsetStr].find("input[id^='age']").attr("data-bind", "value: personAge");
myNamespace[currentFielsetStr].find("select[id^='grade']").attr("data-bind", "value: personGrade");
myNamespace[currentFielsetStr].find("span[id^='person']").attr("data-bind", "text: personTitle");
myNamespace[currentFielsetStr].find("input[id^='hasdata']").attr("data-bind", "value: hasData");
//hasdata identifies visibility and should wipe fields when set to false
myNamespace[currentFielsetStr].attr("data-bind", "visible: hasData() === 'Yes'");
//remove link associates with removeItem function
myNamespace[currentFielsetStr].find("a[id^='remove']").attr("data-bind", "click: removeItem");
//create each viewmodel object
myNamespace.personObjects.push({
"name": myNamespace[currentFielsetStr].find("input[id^='name']").val(),
"age": myNamespace[currentFielsetStr].find("input[id^='age']").val(),
"grade": myNamespace[currentFielsetStr].find("select[id^='grade']").val(),
"hasData": myNamespace[currentFielsetStr].find("input[id^='hasdata']").val(),
"parentFieldset": myNamespace[currentFielsetStr]
});
/*
//attach event handlers
myNamespace[currentFielsetStr].on("click", ".remove", function () {
//retrieve the ko context
var context = ko.contextFor(this);
debugger;
//alert(context);
});
*/
//populate available person array
if (myNamespace.personObjects[i].hasData !== "Yes") {
debugger;
myNamespace.availablePersonObject.push(myNamespace.personObjects[i]);
}
}
//add link associates with addItem function, disables if at maximum count/no positions available -- only one per section -- should try to move to binding outside of these (make a root viewmodel for the page containing individual sections?)
//debugger;
myNamespace.$fieldset0.find("a[id^='addItem']")
.attr("data-bind", "click: addItem, enabled: myNamespace.availablePersonObject.length > 0")
.click(function () {
debugger;
if (myNamespace.availablePersonObject.length > 0) {
//add first item in lsit of available person object (later, based on sort order)
myNamespace.availablePersonObject[0].parentFieldset.find("input[id^='hasdata']").val("Yes").change();
myNamespace.availablePersonObject.splice(0, 1);
}
if (myNamespace.availablePersonObject.length < 1) {
//disable add button
}
});
for (var i = 0; i < myNamespace.personObjects.length; i++) {
//perform knockout bindings
ko.applyBindings(new myViewModel(myNamespace.personObjects[i]), myNamespace.personObjects[i].parentFieldset[0]);
}
});
function myViewModel(personObject) {
var self = this;
self.personName = ko.observable(personObject.name);
self.personAge = ko.observable(personObject.age);
self.personGrade = ko.observable(personObject.grade);
self.hasData = ko.observable(personObject.hasData);
self.personTitle = ko.computed(function () {
return self.personName() + " : " + self.personGrade();
});
self.removeItem = function () {
debugger;
var _blank = "";
//var _blank = undefined;
self.hasData(_blank);
self.personName(_blank);
self.personAge(_blank);
self.personGrade(_blank);
myNamespace.availablePersonObject.push(personObject);
};
/*
self.addItem = function() {
//move this to outside the individual element and add to the parent Section
//or maybe don't have the fields at all
debugger;
};
*/
}
答案 0 :(得分:0)
为我需要解决的问题类型实施了解决方案。
我基本上打破了4个部分的任务,以便绑定到不灵活的生成的HTML。这将在绑定时维护特定的DOM ID(没有为这些目的生成动态html)(这是为每个object-viewModel绑定抽象完成的):
此http://jsfiddle.net/vcbbg81/vv3zjag4/79/
中列出的粗略样本$("#pageMenu1").before("<!-- ko stopBinding: true -->");
$("#pageMenu1").after("<!-- /ko -->");
//$("#employmentMenu1").attr("data-bind", "checked: employmentMenuItem");
myNamespace.vmPage = {
"employmentMenuItem": $("#employmentMenu1").attr("data-bind", "checked: employmentMenuItem").prop("checked"),
"selfEmploymentMenuItem": $("#selfEmploymentMenu1").attr("data-bind", "checked: selfEmploymentMenuItem").prop("checked"),
"otherMenuItem": $("#otherMenu1").attr("data-bind", "checked: otherMenuItem").prop("checked"),
"noneMenuItem": $("#noneMenu1").attr("data-bind", "checked: noneMenuItem").prop("checked")
};
//myNamespace.vmPage = pageObjects;
myNamespace.vmPage.viewModel = new aPageViewModel(myNamespace.vmPage);
ko.applyBindings(myNamespace.vmPage.viewModel, $("#pageMenu1")[0]);