[英]How to obtain input from multiple textareas and radio buttons on the click of a button using knockout?
我在ko: foreach
綁定中動態生成了幾個textareas和單選按鈕。 當用戶確定輸入完畢時,他們將單擊“確定”按鈕,該按鈕將接受文本區域的所有輸入以及他們選擇的單選按鈕的值,並且應該觸發對服務器的ajax調用,因為輸入需要存儲在數據庫中。 每個textarea和單選按鈕值都分別存儲,因此需要將它們作為區別值發送到服務器。 給定foreach
綁定給我帶來了很多麻煩,所以我不確定從哪里開始,因為文本區域沒有可訪問的唯一標識符,因為它們是使用foreach
生成的。 謝謝。
因此,簡單來說:
感謝您提供任何幫助,或鏈接到我可以關注的任何資源。 我的Google搜索未完全回答我的問題。
圖片:
服務器:
//retrieves form data from the client and serialized it
if (Request.HttpMethod == "POST")
{
// get json out of body
var serializer = new JsonSerializer();
var sr = new StreamReader(Request.InputStream);
var jtr = new JsonTextReader(sr);
dynamic data = serializer.Deserialize(jtr);
if (data.action == "getProjects")
{
getProjects(data);
}
}
通過ajax發布的示例對象:
Obj = {};
Obj.action = "getProjects";
Obj.list = arrayOfCheckboxValues;
視圖:
<!-- ko foreach: projects -->
<div id="eachOppyProject">
<table>
<tbody>
<tr>
<td><a data-bind="attr: { href: '/tools/oppy/' + guid }"><span class="link" data-bind="value: guid, text: name"></span></a></td>
</tr>
<tr data-bind="text: projectDescription"></tr>
</tbody>
</table>
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-default" data-bind="visible: firstAnswers, click: function () { showBtnOK(); showDoneTA(); }">
<input type="radio" class="btn btn-default" />
Did it already
</label>
<label class="btn btn-default" data-bind="visible: firstAnswers, click: function () { showInterestedTA(); showBtnOK(); }">
<input type="radio" class="btn btn-default" />Didn't do it, but interested</label>
<label class="btn btn-default" data-bind="visible: firstAnswers, click: function () { neverInterested(); showBtnOK(); }">
<input type="radio" class="btn btn-default" />Never done it; not interested</label>
</div>
<div data-bind="visible: doneAnswer">
<textarea placeholder="Tell us a little of what you've done. Like, when did you do it? Who was in charge of it? Things like that."
class="form-control newSessionAnalyst" data-bind="textInput: doneProject, attr: { id: guid, name: guid + 'doneProject' }"
/>
<textarea placeholder="If there's anything else you'd like us to know, tell us here."
class="form-control newSessionAnalyst" data-bind="textInput: doneProjectComment, attr: { id: guid, name: guid + 'doneProjectComment' }"/>
</div>
<div data-bind="visible: interestedAnswer">
<textarea placeholder="So, you're interested, huh? Tell us why."
class="form-control newSessionAnalyst" data-bind="attr: { id: guid, name: guid + 'interestedProject' }"/>
<textarea placeholder="If there's anything else you'd like us to know, tell us here."
class="form-control newSessionAnalyst" data-bind="attr: { id: guid, name: guid + 'interestedProjectComment' }"/>
</div>
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-default" data-bind="visible: doneAnswer, click: function () { showBtnOK(); showInterestedMoreTA(); }">
<input type="radio" class="btn btn-default" />
Interested in doing more</label>
<label class="btn btn-default" data-bind="visible: doneAnswer, click: function () { showBtnOK(); notInterestedMore(); }">
<input type="radio" class="btn btn-default" />
No plans to do this again</label>
</div>
<div data-bind="visible: interestedMore">
<textarea placeholder="You want to do more? Way to go! Tell us more!"
class="form-control newSessionAnalyst" data-bind="attr: { id: guid, name: guid + 'interestedMore' }, value: $parent.saved_value"/>
<textarea placeholder="If there's anything else you'd like us to know, tell us here."
class="form-control newSessionAnalyst" data-bind="attr: { id: guid, name: guid + 'interestedMoreComment' }"/>
</div>
<div style="text-align: right;">
<input type="button" data-bind="visible: btnOK, click: function () { clearView(); }" value="OK" class="btn btn-default "/><br /><br />
</div> //this is the button that captures all input
</div>
<!-- /ko -->
查看模型:
function ViewModel(proj) {
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.firstAnswers = ko.observable(true);
self.doneAnswer = ko.observable(false);
self.showDoneTA = function () {
self.doneAnswer(true);
self.interestedAnswer(false);
}
self.interestedAnswer = ko.observable(false);
self.showInterestedTA = function () {
self.interestedAnswer(true);
self.doneAnswer(false);
self.interestedMore(false);
}
self.interestedMore = ko.observable(false);
self.showInterestedMoreTA = function () {
self.interestedMore(true);
}
self.notInterestedMore = function () {
self.interestedMore(false);
}
self.neverInterested = function () {
self.doneAnswer(false);
self.interestedAnswer(false);
self.interestedMore(false);
}
self.btnOK = ko.observable(false);
self.showBtnOK = function () {
self.btnOK(true);
console.log(self.btnOK());
}
self.savedMSG = ko.observable(false);
self.clearView = function () {
self.firstAnswers(false);
self.doneAnswer(false);
self.interestedAnswer(false);
self.interestedMore(false);
self.btnOK(false);
self.savedMSG(true);
}
self.showFirstAnswers = function () {
self.firstAnswers(true);
self.savedMSG(false);
}
return self;
}
在foreach中生成文本區域不是問題,並且它們不需要唯一的標識符。
我不確定是什么:
var wrappedProjects = proj.map(function (p) {
return new Project(p);
});
可以,但是假設它生成一個Projects數組,則foreach很好。 我確實注意到並非您所有的textareas都具有值綁定,這將導致它們不填充值。
我確實看到了這個綁定:$ parent.saved_value。 在這種情況下,$ parent將是ViewModel,並且未定義。
在更改foreach之前,我在使用foreach時遇到了錯誤:
<textarea/>
至:
<textarea></textarea>
淘汰賽拋出一個錯誤,指出foreach未關閉。
我懷疑您是從“ jQuery心態”着手解決此問題的,因為您執行的操作是這樣的:
<textarea class="form-control newSessionAnalyst" data-bind="textInput: doneProjectComment, attr: { id: guid, name: guid + 'doneProjectComment' }"/>
在我看來,您正在嘗試設置唯一的ID和名稱,希望在提交時使用jQuery讀取輸入的val()。 雖然我不知道您的textInput
綁定是什么,但是似乎doneProjectComment
在您的Project
數據模型上不是可觀察到的,因此在<textarea>
中輸入的數據並沒有真正結束。
Knockout的方法是在您的Project
上添加一個doneProjectComment
可觀察的對象,並使用value
綁定將其綁定:
<textarea class="form-control newSessionAnalyst" data-bind="value: doneProjectComment"/>
function Project(proj) {
self.doneProjectComment = ko.observable();
}
敲除為您提供雙向綁定。 如果使用value: doneProjectComment
綁定,則意味着如果用戶在文本區域中鍵入內容,則該值將保存到doneProjectComment
。 如果doneProjectComment
更改,則新值將顯示在文本區域中。
因此,如果您想在用戶單擊“確定”時收集所有數據,則可以從Project
內部輕松進行操作-只需閱讀您關心的所有可觀察對象,然后創建一個jQuery.post
可以用作AJAX參數的哈希即可:
function Project(proj) {
self.toAjaxParameters = function(){
return {
interested: self.interestedAnswer(),
done: self.doneAnswer(),
...
}
}
}
HTML:
如果在ViewModel上設置save
功能
self.save = function(project){
$.post('/url-to-post-to', project.toAjaxParameters());
}
HTML:
<button data-bind="click:$parent.save"></button>
我建議安裝Knockout Context Debugger,它使調試敲除問題變得容易得多。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.