Knockout JS ObservableArray失去价值

时间:2016-02-01 16:52:14

标签: knockout.js

我是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])行。

1 个答案:

答案 0 :(得分:1)

当迭代或以任何其他方式处理您的可观察数组时,您需要记住在末尾添加括号,如下所示:

   return ko.utils.arrayFilter(self.functionalAreas(), self.activeFilter());

只有在使用observableArray上实际实现的方法(如push,remove等)时,才能省略括号。