Come inserire in modo condizionale un elemento in un array osservabile?


103

Vorrei pushun nuovo articolo su un observableArray, ma solo se l'articolo non è già presente. Esiste una funzione "trova" o uno schema consigliato per ottenere ciò in KnockoutJS?

Ho notato che la removefunzione su un observableArraypuò ricevere una funzione per il passaggio di una condizione. Voglio quasi la stessa funzionalità, ma spingerla solo se la condizione passata è o non è vera.

Risposte:


223

Un ObservableArray espone una indexOffunzione (wrapper to ko.utils.arrayIndexOf). Questo ti permette di fare:

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

Se i due non sono effettivamente un riferimento allo stesso oggetto e desideri eseguire una logica di confronto personalizzata, puoi utilizzare ko.utils.arrayFirstcome:

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

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

Questo fa un confronto di tutte le proprietà su itemToAdd? Devo solo testare una proprietà Id.
Giaffa

5
Questo controllerà che i due siano lo stesso identico oggetto. Se è necessario verificare singole proprietà, è possibile utilizzare ko.utils.arrayFirst. Aggiungerò un esempio alla risposta.
RP Niemeyer

4
Suggerimento eccellente, ma ho dovuto cambiare itemToAdd.id === item.id in itemToAdd.id () === item.id (). Ho pubblicato il mio codice nella risposta successiva.
Rake36

1
@ Rake36 questo dipenderà dal fatto che tu pensi che gli ID del tuo articolo cambieranno mai e che debbano essere osservabili.
Louis

1
@spaceman - che problema stai riscontrando ===? Hai un campione? Stai confrontando stringhe con numeri o qualcosa del genere?
RP Niemeyer

11

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

    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 quanto segue ($ parent è dovuto al fatto che si trova all'interno di un ciclo di righe di 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

cerca 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

Aggiungerei "valueWillMutate ()" prima delle modifiche e "valueHasMutated ()" dopo di esse.

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();
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.