我一直在学习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部分可能存在一些错误。
答案 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());
答案 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
任何问题以防万一我们都知道