无法处理绑定“foreach:function(){return filter.filters}”消息:未定义过滤器

时间:2014-03-17 03:23:29

标签: knockout.js foreach

我在视图模型中运行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\">&lt;&lt;</a><a href=\"#\" data-bind=\"click: pager.movePrevious, enable: pager.currentPageIndex() > 0\">&lt;</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()\">&gt;</a><a href=\"#\" data-bind=\"click: pager.moveLast, enable: pager.currentPageIndex() < pager.maxPageIndex()\">&gt;&gt;</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>

2 个答案:

答案 0 :(得分:0)

你所拥有的任何变量都没有被定义为ko.observable。您应该使用 ko mapping将模型转换为视图模型。也许你已经在你没有在代码中展示的constractors中完成它,但这是抛出你已经得到的异常的事情之一

答案 1 :(得分:0)

我也遇到过这个问题,因为第二个参数是ko.applyBindings(viewModel, jsObject)的空值,你可以尝试测试它。