挖空数据,在 foreach 内绑定文本区域



在一个foreach中,我有一个span标签和一个文本区域。 每当我单击span标签时,我都想切换文本区域的可见性。

这部分有效,除了它切换了foreach内所有文本区域的可见性,而不仅仅是我所在的特定项目的文本区域。

这是我的代码。 代码实际上并没有运行,但我认为那里有足够的内容让您看到我正在尝试做什么。

function MyViewModel(data) {
 var self = this;
 self.checkListItems = [1,2,3];
 self.textAreaVisible = ko.observable(false);
 
 self.toggleTextArea = function () {
        self.textAreaVisible(!self.textAreaVisible());
 }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="foreach: MyViewModel.checkListItems">
         <span data-bind="click: toggleTextArea">Add Comments ></span>
         <textarea data-bind="value: comments, visible: textAreaVisible"></textarea>
</div>

我在这里找到了这个链接 http://knockoutjs.com/documentation/foreach-binding.html 听起来也许我应该以某种方式使用$data,但我不确定如何让它在这种情况下工作。

感谢您提供的任何帮助。

您可以为文本区域模型创建构造函数。并具有用于可见性的独立变量,并切换可见性

function TextAreaModel(text){
    var self = {};
    self.comments = ko.observable(text);
    self.visible = ko.observable(false);
    self.toggleVisible = function(){
    self.visible(!self.visible());
    };
    return self;
}
function MyViewModel() {
    var self = {};
    self.checkListItems = [
        TextAreaModel("This is some text"), 
        TextAreaModel("This is some more text")
    ];
    return self;
}
var vm = MyViewModel();
ko.applyBindings(vm);

工作示例:https://jsfiddle.net/8n6pghuo/

您的清单项目应该看起来更像这样(即对象(:

self.checkListItems = [
    { value: 1, visible: ko.observable(false) },
    { value: 2, visible: ko.observable(false) },
    { value: 3, visible: ko.observable(false) },
];

这样做可以像这样进行迭代:

<div data-bind="foreach: MyViewModel.checkListItems">
         <span data-bind="click: function(){ visible(!visible()) }">Add Comments ></span>
         <textarea data-bind="value: value, visible: visible"></textarea>
</div>

如果要清理单击处理程序,可以按如下方式修改视图模型:

function MyViewModel(data) {
 //rest of the code
 self.toggleTextArea = function (item) {
    item.visible(!item.visible());
 }
}

将 dom 更改为:

 <div data-bind="foreach: MyViewModel.checkListItems">
             <span data-bind="click: $parent.toggleTextArea">Add Comments ></span>
             <textarea data-bind="value: value, visible: visible"></textarea>
    </div>

就像现在一样,您的问题更像是预期的行为,因为数组上的所有项目的textAreaVisible值都是相同的,因为它是根视图模型的属性。

您需要另一个具有自己的可观察量的视图模型才能随心所欲地工作,因此您将拥有ko.observableArray视图模型,每个视图模型及其用于控制流的可观察量。

这就是你的做法。要隐藏和显示的布尔值必须放置在数组内,以便每个对象都有自己的布尔值来显示或隐藏。

function checkListItemViewModel(number) {
  var self = this;
  self.item = ko.observable(number);
  self.comments = ko.observable("");
  self.isVisible = ko.observable(false);
  self.toggleTextArea = function () {
    self.isVisible(!self.isVisible());
  }
}
function MyViewModel(data) {
  var self = this;
  self.checkListItems = ko.observableArray();
  for (var i = 0; i<data.length; i++) {
    self.checkListItems.push(new checkListItemViewModel(data[i]));
  }
}
ko.applyBindings(new MyViewModel([1, 2, 3]));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="foreach: checkListItems">
  <button data-bind="click: toggleTextArea">Add Comments ></button>
  <textarea data-bind="value: comments, visible: isVisible">
  </textarea>
  <span data-bind="text: comments"></span><br/>
</div>

最新更新