Knockout.js 如何获取所选项目数据?
我的背景主要是asp.net/c,我对Durandal/Knockout还不熟悉。我试图构建一个视图来显示对象列表,并在选择一个项目时显示所选项目的数据。我的问题是,无论选择什么项目,返回的数据总是最后一个项目的数据 以下是我的看法 ... 未显示标记Knockout.js 如何获取所选项目数据?,knockout.js,Knockout.js,我的背景主要是asp.net/c,我对Durandal/Knockout还不熟悉。我试图构建一个视图来显示对象列表,并在选择一个项目时显示所选项目的数据。我的问题是,无论选择什么项目,返回的数据总是最后一个项目的数据 以下是我的看法 ... 未显示标记 <div data-bind="visible: convenios().length > 0" style="height:30px"> Pesquisa retornou <span data-bind="text
<div data-bind="visible: convenios().length > 0" style="height:30px">
Pesquisa retornou <span data-bind="text: convenios().length"></span> conveniados.
</div>
<div class="row-fluid">
<section class="grd-convenio" data-bind="foreach: convenios" style="width:25%; height:300px; overflow-y: scroll">
<article>
<div class="grd-convenio-detalhe" title="Clique para alterar">
<span class="grd-convenio-nome" data-bind="text: nome"></span>
<span class="grd-convenio-id" data-bind="text: id"></span><br/>
<span class="grd-convenio-cidade" data-bind="text: cidade"></span>
<span class="grd-convenio-ativo" data-bind="text: servicosativos"></span>
</div>
</article>
</section>
</div>
})),
视图按预期显示,但当我选择任何项时,bindEventTolist函数中返回的数据(ko.datafor)始终是最后一项的数据。我做错了什么?这是这种应用的好方法吗?TIA.如果您希望在单击项目时显示新视图,可以使用splat(例如router.mapNav('item/:id'))将新项目视图路由添加到durandal路由器,然后更改标记以包含指向新路由的链接。大概是这样的:
<section class="grd-convenio" data-bind="foreach: convenios" style="width:25%; height:300px; overflow-y: scroll">
<article>
<a class="grd-convenio-detalhe" title="Clique para alterar" data-bind="attr: {href: '#/item/' + $data.id}">
<span class="grd-convenio-nome" data-bind="text: nome"></span>
<span class="grd-convenio-id" data-bind="text: id"></span><br/>
<span class="grd-convenio-cidade" data-bind="text: cidade"></span>
<span class="grd-convenio-ativo" data-bind="text: servicosativos"></span>
</a>
</article>
</section>
我个人更喜欢此解决方案,因为它遵循单一责任原则,将所有特定于项目的逻辑处理到新路线的viewmodel。
我更新了你的小提琴,但花了不少时间:)
你让它变得比需要的更难,所以我尝试在你的代码上添加一些标记,以显示我所做的更改,如果我能记住的话。我回去做的最大的一件事就是使用camelCase重命名您的方法,以确保不存在拼写错误。接下来,我将parter函数从viewModel中删除,因为它本身就是一个类,不需要在其中定义
然后我给你的视图模型一个self=this的范围。这只是让视图模型知道,其中的任何内容都有一个self。前身定义为此范围的一部分
接下来,因为我不是JSFIDLE大师,而您试图同时使用jQuery($.each)和KnockOut(ko),所以我将$.each替换为一个名为ko.utils.arrayForEach()的KnockOut实用程序,这基本上是一样的
我怀疑,当您使用$执行forEach循环时,代码中的每一个都将该值设置为selectedPartner的值,然后当您显示selectedPartner时,它只是显示您在forEach循环中设置的最后一个值
如果您想获取一些原始代码并重新使用它,我建议您做的最大的事情就是删除对这么多库的依赖。在试图理解基本JavaScript的同时,同时学习jQuery、Knockout和Durandal,这让您感到困惑。一步一个脚印地做,否则你会得到很多代码,这些代码做的事情你都不知道为什么
function partner(id, name) {
var self = this;
self.id = ko.observable(id);
self.pName = ko.observable(name);
}
function viewmodel() {
var self = this;
self.initialdata = ko.observableArray([
{ id: 1, name: "name1" } ,
{ id: 2, name: "name2" } ,
{ id: 3, name: "name3" } ,
{ id: 4, name: "name4" } ,
]);
self.partners = ko.observableArray();
self.selectedPartner = ko.observable();
self.loadData = function () {
self.partners([]);
ko.utils.arrayForEach(self.initialdata(), function (item) {
self.partners.push(new partner(item.id, item.name));
});
};
self.showSelectedPartner = function (selected) {
alert(selected.pName());
}
}
ko.applyBindings(new viewmodel());
你的看法呢
<section>
<div>
<button data-bind="click: loadData">Load Data</button>
</div>
<div data-bind="visible: partners().length > 0" >Query returned <span data-bind="text: partners().length"></span> records</div>
<div>
<section data-bind="foreach: partners" >
<article>
<div title="Click to Update" data-bind="click: $parent.showSelectedPartner"> <span data-bind="text: id"></span>
<span data-bind="text: pName"></span>
</div>
</article>
</section>
</div>
</section>
加载数据
查询返回的记录
我在你的div上放了一个点击绑定,因为viewAttached是一个Durandal方法,让路由器知道视图已经完成了连接,它可以做一些事情。您创建的bindToEventList只是说,如果单击了与您命名的类相关的任何内容,就会触发该方法。这一切都很好用,而且效率更高,但如果您只是在学习KnockOut,我建议您首先学习绑定的工作原理 “返回最后一项数据”是什么意思?您的警报设置为显示单击的内容,但它不会对该数据做任何操作。@kadumel这就是问题所在。警报始终显示最后一个项目的属性“nome”,而不是实际单击项目的属性“nome”。我需要获取点击项目的id以显示其数据,但由于我总是获取最后一个项目的数据,所以我还没有做任何事情。我只是显示一个返回“nome”的警报。由于语言的差异,理解代码有点困难,但是出于所有目的,您的alert()应该显示当前对象。你能不能制作一个小提琴来重新制作这个问题,这样我们就可以看到背景中发生了什么?抱歉@kadumel。虽然js代码还可以,但我无法让小提琴工作。你知道,我对所有这些工具都不熟悉。但是如果你想看一下[小提琴]()。我相信这会帮助你理解。我点击的任何物品,alert总是返回'name4'。@kadumel,我在小提琴[新小提琴]上做了一点小改动(),谢谢@jaq316。创建一个视图来处理该项可能是一个解决方案,但我真正想找到的是一种将对象“convenio”绑定到单击的元素的方法。ko.数据用于(本);始终返回集合中最后一个“convenio”对象,而不是单击的对象。非常感谢。我真的很感激你的提示和建议。使用您的JSFIDLE,我成功地修复并运行了我的原始代码。我打算在不久的将来在Durandal/Knockout中开发应用程序,我需要快速学习。关于这个问题,我将多读一些书。谢谢你@Kadumel。我确实理解Durandal代码,并且对它很满意。我只是不知道应该使用哪一个,单击binding还是Durandal事件处理程序。顺便说一句,真正修复我的原始代码的是将initialData声明为可观察数组。再次感谢你。很酷回答了你的问题你可以接受答案。祝你好运
<section>
<div>
<button data-bind="click: loadData">Load Data</button>
</div>
<div data-bind="visible: partners().length > 0" >Query returned <span data-bind="text: partners().length"></span> records</div>
<div>
<section data-bind="foreach: partners" >
<article>
<div title="Click to Update" data-bind="click: $parent.showSelectedPartner"> <span data-bind="text: id"></span>
<span data-bind="text: pName"></span>
</div>
</article>
</section>
</div>
</section>