2016-08-26 7 views
0

Ich benutze Knockout, um ein observableArray basierend auf den geprüften Werten eines separaten ObservableArray zu füllen. Ich kann die $ Daten in den zweiten Satz kopieren, aber nur eine Eigenschaft kommt durch. Ich hätte gerne das gesamte Objekt zur Verfügung. Ist das ein Zuordnungsproblem oder etwas mit den Bindungen?Knockout observableArray aktualisiert nicht alle Eigenschaften für checked Wert

HTML:

<form role="form" data-bind="foreach: Colors"> 
     <input type="checkbox" data-bind="checkedValue: name, click: $root.ToggleAssociation, checked: $root.ColorChoice"> 
     <label data-bind="attr: {'for' : name}, text: id() + ' ' + name()"></label> 
    </form> 
    <div data-bind="foreach: ColorChoice"> 
     <span data-bind="text: $rawData.Id, style: { 'background-color': $rawData.Name }"></span> 
    </div> 

JavaScript:

function Color(data) { 
     var self = this; 

     self.id = ko.observable(data.id); 
     self.name = ko.observable(data.name); 
     self.selected = ko.observable(false); 
    } 

    function viewModel() { 

     var self = this; 

     self.Colors = ko.observableArray([]); 
     self.ColorChoice = ko.observableArray(); 

     self.Id = ko.observable(); 
     self.Color = ko.observable(); 

     self.init = function() { 
     self.Colors.push(new Color({ id: 1, name: 'Red' })); 
     self.Colors.push(new Color({ id: 2, name: 'Orange' })); 
     self.Colors.push(new Color({ id: 3, name: 'Yellow' })); 
     self.Colors.push(new Color({ id: 4, name: 'Green' })); 
     self.Colors.push(new Color({ id: 5, name: 'Blue' })); 
     self.Colors.push(new Color({ id: 6, name: 'Purple' })); 
     } 

     self.ToggleAssociation = function (item) { 
     if (item.selected() === true) 
      console.log("dissociate item " + item.id()); 
     else 
      console.log("associate item " + item.id() + " " + item.name()); 
     self.Id(item.id()); 
     self.Color(item.name()); 
     item.selected(!(item.selected())); 
     return true; 
     }; 
    }; 

    var vm = new viewModel(); 
    ko.applyBindings(vm); 
    vm.init(); 

https://jsfiddle.net/Razzle/ff1945ye/

Antwort

0

Sie haben einen Zugriff auf alle Ihre Variablen in Ihrem Modell. Wenn ich genau verstehe, was Sie versuchen zu tun, und Sie möchten das Ereignis click binden, wenn das Kontrollkästchen aktiviert ist, müssen Sie etwas wie das tun.

Beispiel: https://jsfiddle.net/kyr6w2x3/77/

HTML:

<form role="form" data-bind="foreach: Colors"> 
    <input type="checkbox" data-bind="checkedValue: name, click: $root.ToggleAssociation ,checked:selected"> 
    <label data-bind="attr: {'for' : name}, text: id() + ' ' + name()"></label> 
</form> 
<div data-bind="foreach: ColorChoice"> 
    <span data-bind="text: name, style: { 'background-color':name }" class="colors"></span> 
</div> 

JS:

function Color(data) { 
    var self = this; 

    self.id = ko.observable(data.id); 
    self.name = ko.observable(data.name); 
    self.selected = ko.observable(false); 
} 

function viewModel() { 

    var self = this; 

    self.Colors = ko.observableArray([]); 
    self.ColorChoice = ko.observableArray(); 

    self.Id = ko.observable(); 
    self.Color = ko.observable(); 

    self.init = function() { 
    self.Colors.push(new Color({ id: 1, name: 'Red' })); 
    self.Colors.push(new Color({ id: 2, name: 'Orange' })); 
    self.Colors.push(new Color({ id: 3, name: 'Yellow' })); 
    self.Colors.push(new Color({ id: 4, name: 'Green' })); 
    self.Colors.push(new Color({ id: 5, name: 'Blue' })); 
    self.Colors.push(new Color({ id: 6, name: 'Purple' })); 
    } 

    self.ToggleAssociation = function (item) { 
    // here you can go through your array and do whatever you want to do 
    item.selected(!item.selected()); 
    ko.utils.arrayFirst(self.Colors(), function (color) { 
     if(color.id() == item.id()){ 
     if (item.selected()){self.ColorChoice.push(color); 
     }else{self.ColorChoice.remove(color); 
     } 
     } 
    }); 
    return true; 
    }; 
}; 

var vm = new viewModel(); 
ko.applyBindings(vm); 
vm.init(); 
+0

Nice - danke! Also überprüft die ko.utils.arrayFirst das sekundäre Array, ob das Objekt übereinstimmt? – Razzle

+0

'ko.utils.arrayFirst' führt eine Funktion für jedes Element im Array aus und gibt das erste Element zurück, bei dem die Funktion 'wahr' ergibt. Wir durchlaufen das Haupt-Array und was auch immer zu dem ausgewählten Element passt, schieben wir in das zweite Array und wenn es nicht ausgewählt ist, entfernen wir es daraus. –

+0

Verstanden! Danke noch einmal. – Razzle

0

Sie können dies tun, in viel einfachere Art und Weise wie unter

function Color(data) { 
 
    var self = this; 
 
    self.id = ko.observable(data.id); 
 
    self.name = ko.observable(data.name); 
 
    self.selected = ko.observable(false); 
 
} 
 

 
function viewModel() { 
 
    var self = this; 
 
    self.Colors = ko.observableArray([]); 
 
    self.ColorChoice = ko.observableArray([]); 
 
    self.init = function() { 
 
     self.Colors.push(new Color({ id: 1, name: 'Red' })); 
 
     self.Colors.push(new Color({ id: 2, name: 'Orange' })); 
 
     self.Colors.push(new Color({ id: 3, name: 'Yellow' })); 
 
     self.Colors.push(new Color({ id: 4, name: 'Green' })); 
 
     self.Colors.push(new Color({ id: 5, name: 'Blue' })); 
 
     self.Colors.push(new Color({ id: 6, name: 'Purple' })); 
 
    } 
 
}; 
 

 
var vm = new viewModel(); 
 
ko.applyBindings(vm); 
 
vm.init();
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script> 
 
<form role="form" data-bind="foreach: Colors"> 
 
    <label> 
 
     <input type="checkbox" data-bind="value: $data, checked:$root.ColorChoice"> 
 
     <span data-bind="text: id() + ' ' + name()"></span> 
 
    </label> 
 
</form> 
 
<div data-bind="foreach: ColorChoice"> 
 
    <span data-bind="text: id() + ' ' + name(), style: { 'background-color':name }"></span> 
 
</div>

+0

Danke! Dies ist eine einfache Lösung, aber ich muss das Click-Ereignis dort behalten. Es war hilfreich, die abgespeckte Version zu sehen. – Razzle

Verwandte Themen