Javascript 如何通过使用foreach绑定的knockout按钮切换文本区域的显示?
我是个新手。对于我的问题,我正在努力使每个项目都有一个按钮和文本区域。文本区域将在页面加载时隐藏。如果我单击按钮,它将显示文本区域(切换)。当前,如果我单击按钮,页面上的所有文本区域都将显示,而不仅仅是相应的文本区域 我希望这方面的修复不会太引人注目,并且涉及到对我的代码的完全修改,因为通过一些魔术,到目前为止,所有其他功能都在工作。我添加了{attr id:guid}(guid是从数据库检索到的项目的唯一标识符)语句,试图建立一个唯一的id,以便触发正确的控件…尽管这不起作用 对不起,我没有一个工作的JFIDLE来显示问题。。。我试图创建一个,但它没有说明问题 JS: HTML:Javascript 如何通过使用foreach绑定的knockout按钮切换文本区域的显示?,javascript,jquery,html,knockout.js,Javascript,Jquery,Html,Knockout.js,我是个新手。对于我的问题,我正在努力使每个项目都有一个按钮和文本区域。文本区域将在页面加载时隐藏。如果我单击按钮,它将显示文本区域(切换)。当前,如果我单击按钮,页面上的所有文本区域都将显示,而不仅仅是相应的文本区域 我希望这方面的修复不会太引人注目,并且涉及到对我的代码的完全修改,因为通过一些魔术,到目前为止,所有其他功能都在工作。我添加了{attr id:guid}(guid是从数据库检索到的项目的唯一标识符)语句,试图建立一个唯一的id,以便触发正确的控件…尽管这不起作用 对不起,我没有一
问题是需要在projects数组中定义
show
observable。目前,所有文本区域都在查看相同的可观察对象。这意味着您还必须将函数showTextArea
移动到projects数组中
也可以考虑重命名你的函数或者完全去掉它。函数名意味着它们直接驱动对视图的更改,这与MVVM模式背道而驰。我建议使用“toggleComments”这样的名称,因为它不引用视图控件
编辑: 例如:function ProjectViewModel(proj) {
//console.log(proj);
var self = this;
self.projects = ko.observableArray(proj);
foreach(var project in self.projects()) {
project.showComments = ko.observable(false);
project.toggleComments = function () {
self.showComments(!self.showComments());
};
}
};
在你的项目中可能有一种更简洁的方法来实现这一点,我只是想证明我的意思,而不用对你提供的代码做太多修改。这很奇怪
data-bind="visible: show"
不提供任何绑定错误,因为ko foreach:project内的绑定上下文是project而不是ProjectViewModel
无论如何,此解决方案应该可以解决您的问题:
function ViewModel() {
var self = this;
var wrappedProjects = proj.map(function(p) {
return new Project(p);
});
self.projects = ko.observableArray(wrappedProjects);
}
function Project(proj) {
var self = proj;
self.show = ko.observable(false);
self.toggleTextArea = function () {
self.show(!self.show());
}
return self;
}
我是否应该将
proj
传递给self.projects=ko.observearray(proj)代码>?目前,proj
是从包含需要显示的数据的服务器返回的JSON。那么函数项目(proj)
在哪里被调用呢?@SKY,好的,所以我的想法是使用新项目(proj)
来包装每个proj
元素,这样每个元素都有自己的show()
和toggleTextArea
属性。我明白了,那么新项目(proj)
实际上什么时候被调用呢?不,wrappedProjects
是一个结果数组,用于填充项目
可观察数组,绑定不变,仍然使用。您需要将绑定更改为data bind=“visible:$parent.show”`到data bind=“visible:show”
和'data bind=click:$parent.toggleTextArea”`到data bind=“click:toggleTextArea”
(因为现在每个项目项都有自己的show
和toggleTextArea
属性集)@SKY,我的坏,return self;
在Project()中丢失。有关有效解决方案,请参阅。能否澄清的含义这意味着您必须将函数showTextArea也移动到Project数组中。
?@SKY-编辑了我的答案。报告我添加了您的解决方案,并对您的语法进行了一些修复(见我编辑的帖子,上面有你的名字)出现了各种问题——我使用了语法,但没有一个有效。单击事件没有任何作用。你有什么想法吗?谢谢你的帮助,我希望我们能够找到解决方案!
function ProjectViewModel(proj) {
//console.log(proj);
var self = this;
self.projects = ko.observableArray(proj);
self.projects().forEach(function() { //also tried proj.forEach(function())
self.projects().showComments = ko.observable(false);
self.projects().toggleComments = function () {
self.showComments(!self.showComments());
};
})
};
function ProjectViewModel(proj) {
//console.log(proj);
var self = this;
self.projects = ko.observableArray(proj);
foreach(var project in self.projects()) {
project.showComments = ko.observable(false);
project.toggleComments = function () {
self.showComments(!self.showComments());
};
}
};
data-bind="visible: show"
function ViewModel() {
var self = this;
var wrappedProjects = proj.map(function(p) {
return new Project(p);
});
self.projects = ko.observableArray(wrappedProjects);
}
function Project(proj) {
var self = proj;
self.show = ko.observable(false);
self.toggleTextArea = function () {
self.show(!self.show());
}
return self;
}