在foreach中绑定textarea的Knockout数据

时间:2017-04-05 20:19:08

标签: knockout.js

在foreach中,我有一个span标签和一个textarea。每当我点击span标签时,我想切换textarea的可见性。

这部分有效,除了它切换了foreach中textareas的所有的可见性,而不仅仅是我所在的特定项目的textarea。

这是我的代码。代码实际上并没有运行,但我认为那里有足够的东西让你看看我想要做什么。



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>
&#13;
&#13;
&#13;

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

感谢您提供的任何帮助。

4 个答案:

答案 0 :(得分:1)

您可以为textarea模型创建构造函数。并且有一个自包含的可见性变量和切换可见性

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/

答案 1 :(得分:0)

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

你需要另一个具有自己的observable的viewmodel才能让它按你喜欢的方式工作,所以你有一个ko.observableArray个视图模型,每个视图模型都带有可观察的控制流。

答案 2 :(得分:0)

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

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>

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

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>

答案 3 :(得分:0)

这是你如何做到的。隐藏和显示的布尔值必须放在数组中,这样每个对象都有自己的布尔值来显示或隐藏。

&#13;
&#13;
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]));
&#13;
<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>
&#13;
&#13;
&#13;