我是Knockout的新手。我成功地提取数据,但试图根据记录是活动还是不活动来过滤它。当我这样做时,它正在发送正确的值,但我的可观察数组是空的。
我用ajax填充它。我的理解是我填充了可观察数组,除非我想写入数据库或获取新数据,否则不需要对服务器进行任何其他命中。因此,一旦该可观察数组具有数据,我应该能够在不再次访问数据库的情况下对其进行过滤。这对我来说似乎不起作用。我想我做错了什么。想法?
以下是代码:
var sgsoip = window.sgsoip || {};
sgsoip.FunctionalAreaViewModel = function (ko, db) {
//'use strict';
var self = this;
self.functionalAreas = ko.observableArray([])
self.headers = [
{ title: '', sortPropertyName: '', asc: true },
{ title: 'Functional Area Name', sortPropertyName: 'FunctionalAreaName', asc: true },
{ title: 'Active', sortPropertyName: 'FunctionalAreaActive', asc: true }
];
self.filters = [
{ title: "Show All", filter: null },
{ title: "Active", filter: function (item) { return item.FunctionalAreaActive == 'true'; } },
{ title: "Inactive", filter: function (item) { return item.FunctionalAreaActive == 'false'; } }
];
self.activeFilter = ko.observable(self.filters[0].filter);
self.setActiveFilter = function (model, event) {
self.activeFilter(model.filter);
}
self.filteredItems = ko.computed(function () {
if (self.activeFilter()) {
return ko.utils.arrayFilter(self.functionalAreas, self.activeFilter()); //When hitting filter self.functionalAreas is empty
} else {
return self.functionalAreas(); //this works as expected
}
});
self.activeSort = self.headers[1];
function _init() {
db.getFunctionalAreas(function (data) {
//var a = [];
ko.utils.arrayForEach(data || [], function (item) {
self.functionalAreas.push(new sgsoip.FunctionalArea(item.FunctionalAreaID, item.FunctionalAreaName, item.FunctionalAreaActive));
});
//self.functionalAreas(a);
});
}
_init();
return {
functionalAreas: functionalAreas,
sortedFunctionalAreas: sortedFunctionalAreas,
removeFunctionalArea: removeFunctionalArea
};
}(ko, sgsoip.DataContext);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<div class="btn-group" data-bind="foreach: filters">
<button class="btn btn-small" data-bind="click: setActiveFilter, text: title"></button>
</div>
<table class="table" id="gridoutput">
<thead>
<tr data-bind="foreach: headers">
<th><a href="#" data-bind="click: filteredItems, text: title"></a></th>
</tr>
</thead>
<tbody data-bind="foreach: filteredItems">
<tr>
<td><a href="javascript:void(0);" data-bind="click: removeFunctionalArea" title="Delete"><i class="icon icon-trash"></i></a></td>
<td data-bind="text: FunctionalAreaName"></td>
<td data-bind="text: FunctionalAreaActive"></td>
</tr>
</tbody>
</table>
编辑 - 为那些提问的人添加了一些缺失的东西。
var sgsoip = window.sgsoip || {};
sgsoip.DataContext = (function ($) {
'use strict';
var me = {
getFunctionalAreas: getFunctionalAreas,
removeFunctionalArea: removeFunctionalArea,
saveFunctionalArea: saveFunctionalArea
};
function getFunctionalAreas(callback) {
var functionalareas = null;
if ($.isFunction(callback)) {
//functionalareas = localStorage["functionalareas"];
//alert('test');
//if (functionalareas != "undefined") {
// callback(functionalareas);
//} else {
$.getJSON('/FunctionalAreas/GetJsonData', function (data) {
//localStorage["functionalareas"] = JSON.stringify(data.FunctionalAreas);
callback(data);
});
//}
}
}
function removeFunctionalArea(functionalArea) {
}
function saveFunctionalArea(functionalArea) {
}
return me;
})(jQuery);
var sgsoip = window.sgsoip || {};
sgsoip.FunctionalArea = function (FunctionalAreaID, FunctionalAreaName, FunctionalAreaActive) {
'use strict';
this.FunctionalAreaID = ko.observable(FunctionalAreaID);
this.FunctionalAreaName = ko.observable(FunctionalAreaName).extend({ required: "Functional Area Name is required" });
this.FunctionalAreaActive = ko.observable(FunctionalAreaActive).extend({ required: "Active is required" });
this.HasError = ko.pureComputed(function () {
return this.FunctionalAreaActive.hasError() || this.FunctionalAreaName.hasError();
}, this);
};
修改 看起来我可以添加更多说明。它不会丢失数据。我一直走过Knockout代码。它确实循环通过observable进行比较。
我得到以下代码:
arrayFilter: function (array, predicate) {
array = array || [];
var result = [];
for (var i = 0, j = array.length; i < j; i++)
if (predicate(array[i], i))
result.push(array[i]);
return result;
},
它永远不会执行result.push(array [i])行。
答案 0 :(得分:1)
当迭代或以任何其他方式处理您的可观察数组时,您需要记住在末尾添加括号,如下所示:
return ko.utils.arrayFilter(self.functionalAreas(), self.activeFilter());
只有在使用observableArray上实际实现的方法(如push,remove等)时,才能省略括号。