KO计算数组过滤器不起作用

KO computed array filter not working

我一直在学习 KO,但只知道我真的花时间从头开始用它创建一个小项目。

我无法理解我的问题,我将简要解释一下逻辑:

您有页面,这些页面可以有页面(子页面)。

/* Defines a Page */
var page = function(ID, alias, body, connections) {
this.ID = ko.observable(ID);
this.alias = ko.observable(alias);
this.body = ko.observable(body);
this.connections = ko.observableArray(connections);
};

var dummyPages = [
new page(1, 'Alias #1', 'Body #1', [5]),
new page(2, 'Alias #2', 'Body #2', []),
new page(3, 'Alias #3', 'Body #3', [2,3]),
new page(4, 'Alias #4', 'Body #4', [5]),
new page(5, 'Alias #5', 'Body #5', [6]),
new page(6, 'Alias #6', 'Body #6', [7]),
new page(7, 'Alias #7', 'Body #7', [1, 4])
];

我在这里尝试做的是使用一个计算函数,该函数将放置在 foreach html 元素上。

<tbody data-bind="foreach: foreachConnectionAliases" style="text-align: left">

它所做的基本上是获取页面的子信息。

这是我的代码:

/* Return the pages that are connected to the clicked one */
this.foreachConnectionAliases = ko.computed(function(){
alert(this.chPages);
if(typeof this.chPages === "undefined")
  return null;

var filtered =  ko.utils.arrayFilter(this.chPages(), function(page) {
                      return this.filterByThisPage(page.ID());
                  });
                  debugger;
return filtered;
}).bind(this);//, { deferEvaluation: true });

/* Finds out if the activeConnection exists for the page we want */
this.filterByThisPage = function(pageID){
alert('filterByThisPage');
ko.utils.arrayForEach(getPageConnections(), function(id) {
  if(id === pageID) return true;
});
return false;
}.bind(this);

/* Receive a page ID and get its connections array */
this.getPageConnections = function(){
alert('getPageConnections');
var getConnections = ko.utils.arrayFirst(this.chPages(), function(page){
                      return this.activeConnection() === page.ID();
                     });

return getConnections.connections();
}

如您所见,我在路上的某个地方设置了许多警报。计算函数中的警报仅触发一次,我认为这是由于 return null.

需要注意的一件重要事情是,假设我希望在我们更改 this.activeConnection() 的值时触发它,它是一个可观察变量,保存我们单击的页面的 ID(以查看儿童)。

任何关于修复代码以及使其更干净的想法都非常感谢,因为我相信我把它复杂化了。

编辑:

我也试过 deferEvaluation: true ,在那种情况下,我的 foreach 数据绑定总是出现未定义的错误。

编辑 2:

http://jsfiddle.net/g1q99jr8/6/

这简要说明了我的情况。 HTML 部分可能有一些错误。

使用您提供的 Fiddle,我更改了您的代码以实现我认为您想要实现的目标。对于数组搜索,我使用了 jQuery.

这是HTML:

<input type="text" placeholder="Write a number, please" id="number" />
<button type="submit" data-bind="click: changeActiveConnection">
    Click me!
</button>
<div style="margin-bottom: 10px"></div>
<div data-bind="foreach:foreachConnectionAliases">
    <input type="text" data-bind="value:alias" />
    <br />
</div>

和JavaScript:

var viewModel = function () {
    var self = this;

    var page = function (ID, alias, body, connections) {
        this.ID = ko.observable(ID);
        this.alias = ko.observable(alias);
        this.body = ko.observable(body);
        this.connections = ko.observableArray(connections);
    };

    var dummyPages = [
        new page(1, 'Alias #1', 'Body #1', [5]),
        new page(2, 'Alias #2', 'Body #2', []),
        new page(3, 'Alias #3', 'Body #3', [2, 3]),
        new page(4, 'Alias #4', 'Body #4', [5]),
        new page(5, 'Alias #5', 'Body #5', [6]),
        new page(6, 'Alias #6', 'Body #6', [7]),
        new page(7, 'Alias #7', 'Body #7', [1, 4])];

    self.chPages = ko.observableArray(dummyPages);
    self.activePage = ko.observable();

    self.changeActiveConnection = function() {
        var number = +$('#number').val();

        // Find the selected page
        var match = $.grep(self.chPages(), function (e, i) {
           return e.ID() == number;
        });

        if (match.length < 1) // No element found
            return;

        self.activePage(match[0]);
    };

    /* Return the pages that are connected to the clicked one */
    self.foreachConnectionAliases = ko.computed(function() {
        var _page = self.activePage();

        if (_page == null || _page.connections().length < 1)
            return [];

        var aliases = [];

        // Loop through the connections of the current page
        _page.connections().forEach(function (e, i) {
            // Find the page again
            var connection = $.grep(self.chPages(), function (el, ix) {
                return el.ID() == e;          
            })[0];

            aliases.push(connection);
        });

        return aliases;
    });
};

ko.applyBindings(new viewModel());

还有一个working Fiddle.

好吧,您正在尝试根据在基于点击功能的文本框中输入的连接 ID 进行过滤。

这里要注意的第一点是不需要使用 computed 这里的点击功能可能对我来说绰绰有余而且可以用非常简单的方式完成

查看模型:

    var viewModel = function () {
    var self = this;
    var page = function (ID, alias, body, connections) {
        this.ID = ko.observable(ID);
        this.alias = ko.observable(alias);
        this.body = ko.observable(body);
        this.connections = ko.observableArray(connections);
    };

    var dummyPages = [
    new page(1, 'Alias #1', 'Body #1', [5]),
    new page(2, 'Alias #2', 'Body #2', []),
    new page(3, 'Alias #3', 'Body #3', [2, 3]),
    new page(4, 'Alias #4', 'Body #4', [5]),
    new page(5, 'Alias #5', 'Body #5', [6]),
    new page(6, 'Alias #6', 'Body #6', [7]),
    new page(7, 'Alias #7', 'Body #7', [1, 4])];

    self.chPages = ko.observableArray(dummyPages);
    self.activeConnection = ko.observable();
    self.foreachConnectionAliases = ko.observableArray();

    /* Return the pages that are connected to the clicked one */

    self.changeActiveConnection = function () {
        self.foreachConnectionAliases([]);
        var conValue = self.activeConnection();

        if (typeof self.chPages === "undefined") return null;

        var filter = ko.utils.arrayFirst(self.chPages(), function (page) {
            if (page.ID() == conValue) return true;
            else return false;
        });

        if(! filter) return true; 

        ko.utils.arrayForEach(filter.connections(), function (id) {
           ko.utils.arrayFilter(self.chPages(), function (page) {
                if (page.ID() == id) {
                    self.foreachConnectionAliases.push(page);
                    return true;
                } else {
                    return false;
                }
            });
        });
    }

};
ko.applyBindings(new viewModel());

工作fiddlehere

如有任何问题请告诉我们