我在视图模型中运行knockout代码时收到以下错误消息:
无法处理绑定“foreach:function(){return filter.filters}”消息:过滤器未定义
调用我的页面时,我希望能够调用MakePageModel以便能够从我的模型加载数据。该模型正在运作。
你能给我的任何帮助都会很棒。
强文
window.makeApp.makeViewModel = (function (ko, datacontext) {
MakePageModel = function (datacontext) {
if (!datacontext) {
datacontext = {};
}
**//Load data to filter, sort and page on**
var self = this;
self.makes = ExtractModels(self, makeLists.getMakeLists, makeList);
var filters = [
{
Type: "text",
Name: "Name",
Value: ko.observable(""),
RecordValue: function (record) { return record.name; }
},
{
Type: "select",
Name: "Status",
Options: [
GetOption("All", "All", null),
GetOption("None", "None", "None"),
GetOption("New", "New", "New"),
GetOption("Recently Modified", "Recently Modified", "Recently Modified")
],
CurrentOption: ko.observable(),
RecordValue: function (record) { return record.status; }
}
];
var sortOptions = [
{
Name: "ID",
Value: "ID",
Sort: function (left, right) { return left.id < right.id; }
},
{
Name: "Name",
Value: "Name",
Sort: function (left, right) { return CompareCaseInsensitive(left.name, right.name); }
},
{
Name: "Status",
Value: "Status",
Sort: function (left, right) { return CompareCaseInsensitive(left.status, right.status); }
}
];
self.filter = new FilterModel(filters, self.makes);
self.sorter = new SorterModel(sortOptions, self.filter.filteredRecords);
self.pager = new PagerModel(self.sorter.orderedRecords);
},
more code..............
})(ko, makeApp.datacontext);
// Initiate the Knockout bindings
ko.applyBindings(window.makeApp.makeViewModel);
HTML代码
<div data-bind="foreach: filter.filters">
<div>
<span data-bind="text: Name"></span>:<br />
</div>
<div data-bind="if: Type == 'select'">
<select data-bind="options: Options, optionsText: 'Name', value: CurrentOption"> </select>
</div>
<div data-bind="if: Type == 'text'">
<input type="text" data-bind="value: Value, valueUpdate: 'afterkeydown'" />
</div>
</div>
感谢。是的我需要添加我的ko.observables。我仍然收到相同的错误消息。
这是我的viewmodel。
window.makeApp.makeViewModel = (function (ko, datacontext) {
//Data
var self = this;
self.makeLists = ko.observableArray();
self.error = ko.observable();
//Operations
//Load initial state from the server, convert it to make instances, then populate self
function MakePageModel(datacontext) {
if (!datacontext) {
datacontext = {};
}
//var self = this;
//self.makes = ExtractModels(self, makeLists, makeList);
var filters = [
{
Type: "text",
Name: "Name",
Value: ko.observable(""),
RecordValue: function (record) { return record.name; }
},
{
Type: "select",
Name: "Status",
Options: [
GetOption("All", "All", null),
GetOption("None", "None", "None"),
GetOption("New", "New", "New"),
GetOption("Recently Modified", "Recently Modified", "Recently Modified")
],
CurrentOption: ko.observable(),
RecordValue: function (record) { return record.status; }
}
];
var sortOptions = [
{
Name: "ID",
Value: "ID",
Sort: function (left, right) { return left.id < right.id; }
},
{
Name: "Name",
Value: "Name",
Sort: function (left, right) { return CompareCaseInsensitive(left.name, right.name); }
},
{
Name: "Status",
Value: "Status",
Sort: function (left, right) { return CompareCaseInsensitive(left.status, right.status); }
}
];
self.filter = new FilterModel(filters, self.makeLists);
self.sorter = new SorterModel(sortOptions, self.filter.filteredRecords);
self.pager = new PagerModel(self.sorter.orderedRecords);
}
function PagerModel(records) {
var self = this;
self.pageSizeOptions = ko.observableArray([1, 5, 25, 50, 100, 250, 500]);
self.records = GetObservableArray(records);
self.currentPageIndex = ko.observable(self.records().length > 0 ? 0 : -1);
self.currentPageSize = ko.observable(25);
self.recordCount = ko.computed(function () {
return self.records().length;
});
self.maxPageIndex = ko.computed(function () {
return Math.ceil(self.records().length / self.currentPageSize()) - 1;
});
self.currentPageRecords = ko.computed(function () {
var newPageIndex = -1;
var pageIndex = self.currentPageIndex();
var maxPageIndex = self.maxPageIndex();
if (pageIndex > maxPageIndex) {
newPageIndex = maxPageIndex;
}
else if (pageIndex == -1) {
if (maxPageIndex > -1) {
newPageIndex = 0;
}
else {
newPageIndex = -2;
}
}
else {
newPageIndex = pageIndex;
}
if (newPageIndex != pageIndex) {
if (newPageIndex >= -1) {
self.currentPageIndex(newPageIndex);
}
return [];
}
var pageSize = self.currentPageSize();
var startIndex = pageIndex * pageSize;
var endIndex = startIndex + pageSize;
return self.records().slice(startIndex, endIndex);
}).extend({ throttle: 5 });
self.moveFirst = function () {
self.changePageIndex(0);
};
self.movePrevious = function () {
self.changePageIndex(self.currentPageIndex() - 1);
};
self.moveNext = function () {
self.changePageIndex(self.currentPageIndex() + 1);
};
self.moveLast = function () {
self.changePageIndex(self.maxPageIndex());
};
self.changePageIndex = function (newIndex) {
if (newIndex < 0
|| newIndex == self.currentPageIndex()
|| newIndex > self.maxPageIndex()) {
return;
}
self.currentPageIndex(newIndex);
};
self.onPageSizeChange = function () {
self.currentPageIndex(0);
};
self.renderPagers = function () {
var pager = "<div><a href=\"#\" data-bind=\"click: pager.moveFirst, enable: pager.currentPageIndex() > 0\"><<</a><a href=\"#\" data-bind=\"click: pager.movePrevious, enable: pager.currentPageIndex() > 0\"><</a>Page <span data-bind=\"text: pager.currentPageIndex() + 1\"></span> of <span data-bind=\"text: pager.maxPageIndex() + 1\"></span> [<span data-bind=\"text: pager.recordCount\"></span> Record(s)]<select data-bind=\"options: pager.pageSizeOptions, value: pager.currentPageSize, event: { change: pager.onPageSizeChange }\"></select><a href=\"#\" data-bind=\"click: pager.moveNext, enable: pager.currentPageIndex() < pager.maxPageIndex()\">></a><a href=\"#\" data-bind=\"click: pager.moveLast, enable: pager.currentPageIndex() < pager.maxPageIndex()\">>></a></div>";
$("div.Pager").html(pager);
};
self.renderNoRecords = function () {
var message = "<span data-bind=\"visible: pager.recordCount() == 0\">No records found.</span>";
$("div.NoRecords").html(message);
};
self.renderPagers();
self.renderNoRecords();
}
function SorterModel(sortOptions, records) {
var self = this;
self.records = GetObservableArray(records);
self.sortOptions = ko.observableArray(sortOptions);
self.sortDirections = ko.observableArray([
{
Name: "Asc",
Value: "Asc",
Sort: false
},
{
Name: "Desc",
Value: "Desc",
Sort: true
}]);
self.currentSortOption = ko.observable(self.sortOptions()[0]);
self.currentSortDirection = ko.observable(self.sortDirections()[0]);
self.orderedRecords = ko.computed(function () {
var records = self.records();
var sortOption = self.currentSortOption();
var sortDirection = self.currentSortDirection();
if (sortOption == null || sortDirection == null) {
return records;
}
var sortedRecords = records.slice(0, records.length);
SortArray(sortedRecords, sortDirection.Sort, sortOption.Sort);
return sortedRecords;
}).extend({ throttle: 5 });
}
function FilterModel(filters, records) {
var self = this;
self.records = GetObservableArray(records);
self.filters = ko.observableArray(filters);
self.activeFilters = ko.computed(function () {
var filters = self.filters();
var activeFilters = [];
for (var index = 0; index < filters.length; index++) {
var filter = filters[index];
if (filter.CurrentOption) {
var filterOption = filter.CurrentOption();
if (filterOption && filterOption.FilterValue != null) {
var activeFilter = {
Filter: filter,
IsFiltered: function (filter, record) {
var filterOption = filter.CurrentOption();
if (!filterOption) {
return;
}
var recordValue = filter.RecordValue(record);
return recordValue != filterOption.FilterValue; NoMat
}
};
activeFilters.push(activeFilter);
}
}
else if (filter.Value) {
var filterValue = filter.Value();
if (filterValue && filterValue != "") {
var activeFilter = {
Filter: filter,
IsFiltered: function (filter, record) {
var filterValue = filter.Value();
filterValue = filterValue.toUpperCase();
var recordValue = filter.RecordValue(record);
recordValue = recordValue.toUpperCase();
return recordValue.indexOf(filterValue) == -1;
}
};
activeFilters.push(activeFilter);
}
}
}
return activeFilters;
});
self.filteredRecords = ko.computed(function () {
var records = self.records();
var filters = self.activeFilters();
if (filters.length == 0) {
return records;
}
var filteredRecords = [];
for (var rIndex = 0; rIndex < records.length; rIndex++) {
var isIncluded = true;
var record = records[rIndex];
for (var fIndex = 0; fIndex < filters.length; fIndex++) {
var filter = filters[fIndex];
var isFiltered = filter.IsFiltered(filter.Filter, record);
if (isFiltered) {
isIncluded = false;
break;
}
}
if (isIncluded) {
filteredRecords.push(record);
}
}
return filteredRecords;
}).extend({ throttle: 200 });
}
function ExtractModels(parent, data, constructor) {
var models = [];
if (data == null) {
return models;
}
for (var index = 0; index < data.length; index++) {
var row = data[index];
var model = new constructor(row, parent);
models.push(model);
}
return models;
}
function GetObservableArray(array) {
if (typeof (array) == 'function') {
return array;
}
return ko.observableArray(array);
}
function CompareCaseInsensitive(left, right) {
if (left == null) {
return right == null;
}
else if (right == null) {
return false;
}
return left.toUpperCase() <= right.toUpperCase();
}
function GetOption(name, value, filterValue) {
var option = {
Name: name,
Value: value,
FilterValue: filterValue
};
return option;
}
function SortArray(array, direction, comparison) {
if (array == null) {
return [];
}
for (var oIndex = 0; oIndex < array.length; oIndex++) {
var oItem = array[oIndex];
for (var iIndex = oIndex + 1; iIndex < array.length; iIndex++) {
var iItem = array[iIndex];
var isOrdered = comparison(oItem, iItem);
if (isOrdered == direction) {
array[iIndex] = oItem;
array[oIndex] = iItem;
oItem = iItem;
}
}
}
return array;
}
datacontext.getMakeLists(makeLists, error); // load update makes
return {
makeLists: self.makeLists,
error: self.error
};
})(ko, makeApp.datacontext);
// Initiate the Knockout bindings
ko.applyBindings(makeApp.makeViewModel);
这是我的html:
<tr>
<td class="LsSearch">
<b>Filters:</b><br />
<div class="" data-bind="foreach: filter.filters">
<div>
<span data-bind="text: Name"></span>:<br />
</div>
<div data-bind="if: Type == 'select'">
<select data-bind="options: Options, optionsText: 'Name', value: CurrentOption"></select>
</div>
<div data-bind="if: Type == 'text'">
<input type="text" data-bind="value: Value, valueUpdate: 'afterkeydown'" />
</div>
</div>
<br />
<b>Sorts:</b>
Field:
<br />
<select data-bind="options: sorter.sortOptions, optionsText: 'Name', value: sorter.currentSortOption"></select>
Direction:
<select data-bind="options: sorter.sortDirections, optionsText: 'Name', value: sorter.currentSortDirection"></select>
<br />
<br />
<table>
<thead>
<tr>
<th>
ID
</th>
<th>
Account ID
</th>
<th>
Name
</th>
<th>
Description
</th>
</tr>
</thead>
<tbody data-bind="foreach: pager.currentPageRecords">
<tr>
<td>
<span data-bind="text: id"></span>
</td>
<td>
<span data-bind="text: accountId"></span>
</td>
<td>
<span data-bind="text: name"></span>
</td>
<td>
<span data-bind="text: description"></span>
</td>
</tr>
</tbody>
</table>
</td>
答案 0 :(得分:0)
你所拥有的任何变量都没有被定义为ko.observable。您应该使用 ko mapping将模型转换为视图模型。也许你已经在你没有在代码中展示的constractors中完成它,但这是抛出你已经得到的异常的事情之一
答案 1 :(得分:0)
我也遇到过这个问题,因为第二个参数是ko.applyBindings(viewModel, jsObject)
的空值,你可以尝试测试它。