如何使淘汰赛填充
问题描述:
我使用淘汰赛建立一个HTML表格如何使淘汰赛填充
<!-- ko foreach: currentPageQuestions -->
<tr>
<td class="question-item" data-bind="html:questionText"></td>
</tr>
<!-- /ko -->
然后我试图使用分页DataTables
筛选此表在页面加载数据:
$(document).ready(function(){
$('#dataTableQuestions').DataTable();
});
由于表没有被完全加载时,数据表的脚本没有找到在页加载的任何元件,而不是分页它。
当我看到HTML通过点击“查看源文件”我看到相同的HTML(与淘汰赛代码)不红素或TDS为观察集合中的所有元素。
虽然我可以看到所有的TR和TD,但是“检查元素”。
所以,只是想知道如果有一种方法,使数据提供的document.ready函数调用的代码被触发前。
在此先感谢。
答
我建议你使用绑定的处理程序要做到这一点,它会更容易维护和数据源的任何变化都会反映在视图,看到片段波纹管的例子:
ko.bindingHandlers.dataTablesForEach = {
\t page: 0,
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var options = ko.unwrap(valueAccessor());
ko.unwrap(options.data);
if(options.dataTableOptions.paging){
\t valueAccessor().data.subscribe(function (changes) {
\t var table = $(element).closest('table').DataTable();
ko.bindingHandlers.dataTablesForEach.page = table.page();
table.destroy();
}, null, 'arrayChange');
}
var nodes = Array.prototype.slice.call(element.childNodes, 0);
ko.utils.arrayForEach(nodes, function (node) {
\t if (node && node.nodeType !== 1) {
\t node.parentNode.removeChild(node); \t
}
});
return ko.bindingHandlers.foreach.init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
},
update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var options = ko.unwrap(valueAccessor()),
key = 'DataTablesForEach_Initialized';
ko.unwrap(options.data);
var table;
if(!options.dataTableOptions.paging){
table = $(element).closest('table').DataTable();
\t table.destroy();
}
ko.bindingHandlers.foreach.update(element, valueAccessor, allBindings, viewModel, bindingContext);
table = $(element).closest('table').DataTable(options.dataTableOptions);
if (options.dataTableOptions.paging) {
if (table.page.info().pages - ko.bindingHandlers.dataTablesForEach.page == 0)
table.page(--ko.bindingHandlers.dataTablesForEach.page).draw(false);
else
table.page(ko.bindingHandlers.dataTablesForEach.page).draw(false);
}
if (!ko.utils.domData.get(element, key) && (options.data || options.length))
ko.utils.domData.set(element, key, true);
return { controlsDescendantBindings: true };
}
};
// Person ViewModel
var Person = function (data, parent) {
var that = this;
this.id = data.id;
this.isEdit = ko.observable(false);
this.first = ko.observable(data.first);
this.last = ko.observable(data.last);
this.age = ko.observable(data.age);
this.editButtonText = ko.computed(function() {
return that.isEdit() ? 'Save' : 'Edit';
});
this.full = ko.computed(function() {
return this.first() + " " + this.last();
}, this);
// Subscribe a listener to the observable properties for the table
// and invalidate the DataTables row when they change so it will redraw
};
//Main ViewModel
var ViewModel = new function() {
var that = this;
this.people = ko.mapping.fromJS([]);
this.inline = ko.observable(true);
this.add = function() {
$('#dialog').dialog('open');
};
this.getEditMode = ko.computed(function() {
return that.inline() ? '(Inline)' : '(Dialog)';
});
this.remove = function (person, event) {
that.people.remove(person);
};
\t this.removeAll = function(person, event){
that.people.removeAll();
};
this.edit = function (person, event) {
if (that.inline()) {
if (person.isEdit()){
person.isEdit(false);
}
else{
that.people().forEach(function(p){
if(p.isEdit()){
p.isEdit(false);
}
});
person.isEdit(true);
}
} else {
$('#editdialog').data('id', person.id);
$('#editName').val(person.first());
$('#editLast').val(person.last());
$('#editAge').val(person.age());
$('#editdialog').dialog('open');
}
};
};
var count = 3;
// Initial data set
var data = [{
id: 1,
first: "Allan",
last: "Jardine",
age: 86
}, {
id: 2,
first: "Bob",
last: "Smith",
age: 54
}, {
id: 3,
first: "Jimmy",
last: "Jones",
age: 32
}];
$(document).ready(function() {
// Convert the data set into observable objects, and will also add the
// initial data to the table
ko.mapping.fromJS(
data, {
key: function (data) {
return ko.utils.unwrapObservable(data.id);
},
create: function (options) {
return new Person(options.data, ViewModel);
}
},
ViewModel.people);
$('#dialog').dialog({
modal: true,
autoOpen: false,
height: 350,
width: 460,
buttons: {
'Add Person': function() {
ViewModel.people.push(new Person({
id: ++count,
first: $('#Name').val(),
last: $('#Last').val(),
age: $('#Age').val()
}, ViewModel));
$('#ID').closest('div').find('input').val('');
$(this).dialog('close');
},
'Close': function() {
$(this).dialog('close');
}
}
});
$('#editdialog').dialog({
modal: true,
autoOpen: false,
height: 350,
width: 460,
buttons: {
'Edit Person': function() {
var id = $(this).data('id');
ko.utils.arrayForEach(ViewModel.people(), function (person) {
if (id == person.id) {
person.first($('#editName').val());
person.last($('#editLast').val());
person.age($('#editAge').val());
}
});
$('#editName').closest('div').find('input').val('');
$(this).dialog('close');
},
'Close': function() {
$(this).dialog('close');
}
}
});
ko.applyBindings(ViewModel);
$('#AddPerson').click(function() {
ViewModel.people.push(new Person({
id: ++count,
first: 'NEW',
last: 'NEW',
age: '99'
}, ViewModel));
});
});
.ui-buttonset .ui-button {
margin-left: 0;
margin-right: 0;
}
body{
background:white;
}
<link href="http://code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.3.5/knockout.mapping.js"></script>
<script src="http://code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>
<script src="http://cdn.datatables.net/1.10.7/js/jquery.dataTables.min.js"></script>
<button data-bind="click: add">ADD</button> Toggle Editing Mode <span data-bind="text: getEditMode"></span>
<input type="checkbox" data-bind="checked: inline" />
<br />
<br/>
<button data-bind="click: removeAll">Remove All</button>
<br />
<br />
<div id="wrapper">
<table id="example" style="width:100%" class="table table-striped table-bordered dataTable">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Age</th>
<th>Remove</th>
<th>Edit</th>
</tr>
</thead>
<!-- you can also pass the dataTablesForEach option as a bind to let the HTML more clean -->
<!-- like this: <tbody data-bind="dataTablesForEach: dataTableOptions"> -->
<tbody data-bind="dataTablesForEach: {data: people, dataTableOptions: {
jQueryUI: true,
scrollY: 250,
paging: true,
dom: 'rtip',
columns:[
{width: '30px'},
{width: '100px'},
{width: '100px'},
{width: '100px'},
{width:'100px'}
]
}
}">
<tr style="height:50px;">
<td><span data-bind="text: id" />
</td>
<td style="width:50px;"> <span data-bind="text: first, visible:!isEdit()"></span>
<input class="form-control input-sm" data-bind="textInput: first, visible: isEdit()" style="width:95%" />
</td>
<td> <span data-bind="text: age, visible:!isEdit()"></span>
<input class="form-control input-sm" data-bind="textInput: age, visible: isEdit()" style="width:95%" />
</td>
<td>
<button class="btn btn-danger" data-bind="click: $parent.remove">Remove</button>
</td>
<td>
<button class="btn btn-primary" data-bind="click: $parent.edit, text: editButtonText, css: {'btn-success': isEdit}"></button>
</td>
</tr>
</tbody>
</table>
<br />
<br />
<div>
<button id="AddPerson">ADD</button>
</div>
<br/>
<br/>
<div>
<textarea rows="20" cols="100" data-bind="text: ko.toJSON($data.people, null, 2)"></textarea>
</div>
<div id="dialog" title="Add New Person" style="display:none">
<label for="Name">First Name</label>
<br />
<input type="text" name="Name" id="Name" />
<br />
<label for="Last">Last Name</label>
<br />
<input type="text" name="Last" id="Last" />
<br />
<label for="Age">Age</label>
<br />
<input type="text" name="Age" id="Age" />
<br />
</div>
<div id="editdialog" title="Edit Person" style="display:none">
<label for="editName">First Name</label>
<br />
<input type="text" name="editName" id="editName" />
<br />
<label for="editLast">Last Name</label>
<br />
<input type="text" name="editLast" id="editLast" />
<br />
<label for="editAge">Age</label>
<br />
<input type="text" name="editAge" id="editAge" />
<br />
</div>
有关处理程序如何绑定工作,在淘汰赛网站上看到有关文件, 任何问题:Custom Bindings
我猜你需要一个[自定义绑定处理程序(http://knockoutjs.com/documentation/custom-bindings.html)来处理类似数据表和KnockoutJS一个基于UI的插件之间的互动。但是,我注意到[datatables.net网站提出了一种不同的方法](http://datatables.net/dev/knockout/)。 – Jeroen
请阅读答案 –