2016-07-11 9 views
0

Der Benutzer muss einen Radiobutton auswählen. Mein Label muss den Wert des ausgewählten Optionsfelds haben, um später in einem Textfeld angezeigt zu werden. Ich brauche auch den Wert des Radiobuttons, der in der Ajax "title" -Variable gespeichert wird, damit ich ihn im Backend (Python - Flask) verwenden kann. Wenn ich auf die Schaltfläche zum Migrieren klicke, wird mein Ajax-Anruf ausgeführt.Wie verwendet man mehrere geprüfte Daten-bindet auf einem einzigen Radio-Button mit KnockoutJS?

Ich lese, dass ich Kommas nur zwischen Datenbindungen setzen kann, aber indem es tut, bricht es meinen Code, wo die Radio-Tasten nicht funktionieren. Wenn ich jedoch nur data-bind="checked: $data.title" mache, dann funktioniert mein Ajax-Anruf, aber mein Etikett bleibt leer (aus offensichtlichen Gründen).

Wie bekomme ich es, damit ich zwei überprüfte Daten-Bindungen auf meinen Optionsfeldern verwenden kann, damit meine Label-Updates und meine Ajax-Aufrufe funktionieren? Oder gibt es eine andere Lösung, die ich vermisse?

Mein Kopf

<!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"> 

My Radio Buttons

<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> 

My Label

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

My Button

<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> 

Mein 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> 

Antwort

0

Ja Sie mehrere Bindungen auf einer einzigen Steuerung verwenden können, aber was Sie versuchen, verwenden mehrere der SAME verbindlich zu tun ist, eine einzige Kontrolle. Wenn Sie den gleichen Bindungstyp auf das Steuerelement anwenden, wird die zweite Verwendung der gleichen Bindung ausgewählt. Du willst das wahrscheinlich nicht machen.

Der in title enthaltene Wert wird aktualisiert, um den Wert des Wertattributs des derzeit ausgewählten Optionsfelds zu enthalten, d. H. value="DevQ" oder value="Dev2" in Ihren Eingaben. Dies bedeutet, dass der in $data.titlegespeicherte Wert genau das ist, wonach Sie suchen! das Optionsfeld, dessen Wert Sie benötigen. Sehen Sie sich das folgende Snippet an. Es hofft, dass es hilft, Dinge für Sie zu klären.

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

Mein aktueller 'ko.applybindings' sieht wie folgt aus' ko.applyBindings (window.viewModel, $ ('# tab') [0]); '. Wie soll ich Bindungen in meinem Szenario anwenden? – ButterJones

+0

Sie können einfach 'var tabViewModel = new TabViewModel();' und dann 'ko.applyBindings (tabViewModel, document.getElementById (tab));' –

+0

Ich bekomme diesen Fehler, wenn ich versuche, was Sie oben haben ... ' knockout-min.js: 63 Uncaught ReferenceError: Binding kann nicht verarbeitet werden "checked: function() {return title}" Nachricht: title is not defined'. Wie soll ich das beheben? – ButterJones

0

Sie können nicht die gleiche Bindungs ​​zweimal auf ein Element haben, zumindest nicht mit der in Bindungen aufgebaut.

Stattdessen sollten Sie Ihre Ansichtsmodelle so strukturieren, dass jede Funktion Zugriff auf den relevanten Bereich hat.

Normalerweise habe ich ein Root- oder Parent-View-Modell, das Ajax-Anforderungen verdrahtet und kleinere View-Modelle für Domänenkonzepte wie task hat.Zum Beispiel:

// 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

Ich bin ein wenig verloren. Können Sie einige Beispiele aus meinem spezifischen Code bereitstellen? – ButterJones