2011-12-07 18 views
102

Desidero specificare push un nuovo articolo su un observableArray, ma solo se l'articolo non è già presente. Esiste una funzione di "trova" o un modello consigliato per ottenere questo risultato in KnockoutJS?Come spingere condizionatamente un oggetto in un array osservabile?

Ho notato che la funzione remove su un observableArray può ricevere una funzione per passare una condizione. Voglio quasi la stessa funzionalità, ma solo spingerlo se la condizione passata è o non è vera.

risposta

221

Un osservableArray espone una funzione indexOf (wrapper su ko.utils.arrayIndexOf). Questo permette di fare:

if (myObservableArray.indexOf(itemToAdd) < 0) { 
    myObservableArray.push(itemToAdd); 
} 

Se i due non sono in realtà un riferimento allo stesso oggetto e si desidera eseguire logica di confronto personalizzato, quindi è possibile utilizzare ko.utils.arrayFirst come:

var match = ko.utils.arrayFirst(myObservableArray(), function(item) { 
    return itemToAdd.id === item.id; 
}); 

if (!match) { 
    myObservableArray.push(itemToAdd); 
} 
+0

Fa un confronto di tutte le proprietà su itemToAdd? Ho solo bisogno di testare una proprietà Id. – jaffa

+5

Ciò verificherà che i due siano esattamente lo stesso oggetto. Se è necessario verificare le proprietà individuali, è possibile utilizzare 'ko.utils.arrayFirst'. Aggiungerò un campione alla risposta. –

+4

Consiglio eccellente, ma ho dovuto modificare itemToAdd.id === item.id in itemToAdd.id() === item.id(). Ho pubblicato il mio codice nella prossima risposta. – Rake36

11

Grazie RP . Ecco un esempio di utilizzo del tuo suggerimento per restituire la proprietà 'name' tramite la proprietà 'id' dell'oggetto all'interno del mio modello di vista.

self.jobroles = ko.observableArray([]); 

    self.jobroleName = function (id) 
    { 
     var match = ko.utils.arrayFirst(self.jobroles(), function (item) 
     { 
      return item.id() === id(); //note the() 
     }); 
     if (!match) 
      return 'error'; 
     else 
      return match.name; 
    }; 

In HTML, ho il seguente ($ genitore è a causa di questo essere all'interno di un ciclo riga della tabella):

<select data-bind="visible: editing, hasfocus: editing, options: $parent.jobroles, optionsText: 'name', optionsValue: 'id', value: jobroleId, optionsCaption: '-- Select --'"> 
          </select> 
<span data-bind="visible: !editing(), text: $parent.jobroleName(jobroleId), click: edit"></span></td> 
0

cercare un oggetto in un ko.observableArray

function data(id,val) 
{ var self = this; 
self.id = ko.observable(id); 
self.valuee = ko.observable(val); } 

var o1=new data(1,"kamran"); 
var o2=new data(2,"paul"); 
var o3=new data(3,"dave"); 
var mysel=ko.observable(); 
var combo = ko.observableArray(); 

combo.push(o1); 
combo.push(o2); 
combo.push(o3); 
function find() 
{ 
     var ide=document.getElementById("vid").value;  
     findandset(Number(ide),mysel); 
} 

function indx() 
{ 
    var x=document.getElementById("kam").selectedIndex; 
    alert(x); 
} 

function getsel() 
{ 
    alert(mysel().valuee()); 
} 


function findandset(id,selected) 
{ 
    var obj = ko.utils.arrayFirst(combo(), function(item) { 
    return id=== item.id(); 
}); 
    selected(obj); 
} 

findandset(1,mysel); 
ko.applyBindings(combo); 


<select id="kam" data-bind="options: combo, 
        optionsText: 'valuee', 
        value: mysel, 
        optionsCaption: 'select a value'"> 

        </select> 
<span data-bind="text: mysel().valuee"></span> 
<button onclick="getsel()">Selected</button> 
<button onclick="indx">Sel Index</button> 
<input id="vid" /> 
<button onclick="find()">Set by id</button> 

http://jsfiddle.net/rathore_gee/Y4wcJ/

0

Vorrei aggiungere "valore WillMutate() "prima delle modifiche e" valueHasMutated() "dopo di loro.

for (var i = 0; i < data.length; i++) { 
    var needChange = false; 
    var itemToAdd = data[i]; 
    var match = ko.utils.arrayFirst(MyArray(), function (item) { 
     return (itemToAdd.Code === item.Code); 
    }); 
    if (!match && !needChange) { 
     MyArray.valueWillMutate(); 
     needChange = true; 
    } 
    if (!match) { 
     MyArray.push(itemToAdd); 
    } 
} 
if (needChange) { 
    MyArray.valueHasMutated(); 
} 
Problemi correlati