簡體   English   中英

如何使用敲除功能在單擊按鈕時從多個文本區域和單選按鈕獲取輸入?

[英]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生成的。 謝謝。

因此,簡單來說:

  1. 用戶鍵入多個文本區域,然后單擊單選按鈕。
  2. 完成鍵入后,用戶單擊“確定”按鈕。 按鈕單擊功能可檢索所有文本區域和單選按鈕值中的用戶輸入。
  3. 觸發ajax調用並將值發送到服務器。

感謝您提供任何幫助,或鏈接到我可以關注的任何資源。 我的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM