KO计算的阵列滤波器不工作

时间:2015-02-02 14:52:40

标签: jquery html knockout.js foreach

我一直在学习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();
}

在路上的某个地方,我已经发出了许多警报,你可以看到。计算函数中的警报只触发一次,我认为它是由于返回null。

需要注意的一件重要事情是,我希望在我们更改this.activeConnection()的值时触发它。这是一个可观察的变量,它保存我们点击的页面的ID(以查看子项)。 / p>

任何关于修复代码以及使代码更加干净的想法都非常受欢迎,因为我相信我已经过于复杂了。

编辑:

我也尝试过deferEvaluation:true,在这种情况下,我总是在foreach数据绑定上得到一个未定义的错误。

编辑2:

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

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

2 个答案:

答案 0 :(得分:1)

使用您提供的小提琴,我已经更改了您的代码,以实现我想要实现的目标。对于数组搜索,我使用了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

答案 1 :(得分:1)

你正试图根据基于点击功能在文本框中输入的连接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());

工作小提琴 here

任何问题以防万一我们都知道