2016-07-11 7 views
0

ユーザはラジオボタンを1つ選択する必要があります。私のラベルは、後でテキストボックスに表示するために、選択したラジオボタンの値を持つ必要があります。バックエンド(Python - Flask)で使用できるように、ラジオボタンの値をAjaxの "title"変数に保存する必要があります。マイグレーション・ボタンをクリックすると、Ajaxコールが実行されます。KnockoutJSを使用して1つのラジオボタンで複数のチェック済みデータバインドを使用する方法は?

私はちょうどデータバインドの間にコンマを置くことができますが、を実行すると、ラジオボタンが動作しない場所にコードが壊れてしまいます。しかし、私がちょうどdata-bind="checked: $data.title"を実行すると、私のAjax呼び出しは機能しますが、私のラベルは空白のままです(明らかな理由により)。

ラジオボタンで2つのチェックされたデータバインドを使用できるようにするには、どうすれば自分のラベルが更新され、Ajaxコールが機能するのですか?それとも私は行方不明の別の解決策はありますか?

マイヘッダ

<!DOCTYPE html> 
<html> 

    <script type='text/javascript' src='http://ajax.aspnetcdn.com/ajax/knockout/knockout-3.4.0.js'></script> 
    <script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/json2/20150503/json2.js'></script> 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script> 
    <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> 

    <meta charset="utf-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 

    <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"> 

    <body> 
     {% extends "layout.html" %} 
     {% block content %} 
     <div id="tab"> 

マイラジオボタン

<td id="myRadioFrom" class="label">From:</td> 
<td> 
    <label><input type="radio" value="DevQ" name="from" data-bind="checked: $data.title, checked: radioFrom" />DevQ</label> 
    <label><input type="radio" value="Dev2" name="from" data-bind="checked: $data.title, checked: radioFrom" />Dev2</label> 
</td> 

マイラベル

<tr> 
    <td class="label">From:</td> 
    <td data-bind="text: radioFrom"></td> 
</tr> 

マイボタン

<form> 
    <span class="migrate"><button data-bind="click: $data.add" type="submit" class="btn btn-default" value="Migrate!" data-dismiss="modal">Migrate!</button></span> 
</form> 

私のJavascript/KnockoutJS

<script> 
    var TabViewModel = function(){ 
     var self = this; 

     //Set href value of element 
     self.selected = ko.observable(null); 

     self.tasksURI = 'http://localhost:5000/todo/api/v1.0/tasks'; // Use to get root access to server 
     self.username = ""; 
     self.password = ""; 
     self.tasks = ko.observableArray(); 

     self.radioFrom = ko.observable(""); 

     var btn = document.getElementById("myBtn");     
     var span = document.getElementsByClassName("close")[0]; 

     controls.onchange = function() { 
      console.log(viewModel.radioFrom()); 
     } 

     self.ajax = function(uri, method, data) 
     { 
      var request = 
      { 
       url: uri, 
       type: method, 
       contentType: "application/json", 
       accepts: "application/json", 
       cache: false, 
       dataType: 'json', 
       data: JSON.stringify(data), 

       // beforeSend is invoked by jQuery, used to send a jqXHR object to get a request from $.aJax 
       beforeSend: function (xhr) 
       { 
        xhr.setRequestHeader("Authorization", 
         "Basic " + btoa(self.username + ":" + self.password)); 
       }, 
       // if $.aJax request comes back with an error such as invalid username 
       error: function(jqXHR) 
       { 
        console.log("ajax error " + jqXHR.status); 
       }    
      }; 
      return $.ajax(request); // Returns value of the $.aJax request 
     } 

     self.add = function(task) 
     { 
      self.ajax(self.tasksURI, 'POST', task).done(function(data) 
      { 
       self.tasks.push 
       ({ 
        uri: ko.observable(data.task.uri), 
        title: ko.observable(data.task.title), 
        description: ko.observable(data.task.description), 
        done: ko.observable(data.task.done) 
       }); 

      }); 
     } 

    }; 
    window.viewModel = new TabViewModel(); 
    ko.applyBindings(window.viewModel, $('#tab')[0]);   
</script> 

答えて

0

はい、あなたは、単一のコントロールに複数のバインディングを使用しますが、あなたが何しようとしていることは上の結合SAMEの使用倍であることができます単一のコントロール。同じタイプのバインディングをコントロールノックアウトに適用すると、同じバインディングの2番目の使用法が選択されます。あなたはおそらくこれをしたくないでしょう。

titleに保持されている値は、現在選択されているラジオボタンのvalue属性の値、つまり入力にvalue="DevQ"またはvalue="Dev2"を含むように更新されます。つまり、$data.titleに格納されている値はになります。つまり値が必要なラジオボタンです。下のスニペットを見てください。それはあなたのために物事を明確にするのに役立ちます。

ko.applyBindings({ 
 
    title: ko.observable('DevQ') 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 
<label> 
 
    <input type="radio" value="DevQ" name="from" data-bind="checked: title" />DevQ</label> 
 
<label> 
 
    <input type="radio" value="Dev2" name="from" data-bind="checked: title" />Dev2</label> 
 
<br/> 
 
<hr/> 
 
<br/>The value held in title() is updated to contain the value of the value attribute of the radio button that is selected 
 
<br/> 
 
<br/> 
 
<b id="myRadioFrom" class="label">From: </b><span data-bind="text: $data.title"></span>

+0

私の現在の 'ko.applybindings'はこの' ko.applyBindings(window.viewModel、$( '#タブ')[0])のように見えます; '。 私のシナリオでバインディングを適用する方法を教えてください。 – ButterJones

+0

'var tabViewModel = new TabViewModel();'と 'ko.applyBindings(tabViewModel、document.getElementById(tab));' –

+0

上記の内容を試してみるとこのエラーが発生します... ' knockout-min.js:63 Uncaught ReferenceError:バインディングを処理できません "checked:function(){return title}" メッセージ:タイトルが定義されていません。これを修正するにはどうすればいいですか? – ButterJones

0

あなたは、少なくともではないバインディングを内蔵した、一つの要素に二度同じ結合を持つことはできません。

代わりに、各関数が関連スコープにアクセスできるようにビューモデルを構造化する必要があります。

通常、Ajaxリクエストを配線するルートまたは親ビューモデルがあり、taskのようなドメイン概念のビューモデルは小さくなりがちです。たとえば、次のように

// Fake jQuery ajax stuff: 
 
var $ = { ajax: function(options) { console.log(options); } }; 
 

 
function Task() { 
 
    this.title = ko.observable(""); 
 
} 
 

 
function RootVm() { 
 
    var self = this; 
 
    
 
    self.user = ko.observable("fake-username"); 
 
    self.password = ko.observable("sec!ret"); 
 
    
 
    self.tasks = ko.observableArray([new Task(), new Task()]); 
 
    
 
    function doAjaxCall(task) { 
 
    $.ajax({ 
 
     data: task.title(), 
 
     user: self.user(), 
 
     password: self.password() 
 
    }); 
 
    } 
 
    
 
    self.migrate = function(task) { 
 
    doAjaxCall(task); 
 
    }; 
 
} 
 

 
ko.applyBindings(new RootVm());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script> 
 

 
<ul data-bind="foreach: tasks"> 
 
    <li> 
 
    Title: 
 
    <input data-bind="textInput: title"> 
 
    <button data-bind="click: $root.migrate">migrate</button> 
 
    </li> 
 
</ul> 
 

 
<hr> 
 

 
User: <input data-bind="textInput: user"><br> 
 
Password: <input data-bind="textInput: password">

+0

私は少し失われています。私の特定のコードからいくつかの例を提供できますか? – ButterJones

関連する問題