web-dev-qa-db-fra.com

Comment pousser conditionnellement un élément dans un tableau observable?

Je voudrais Push un nouvel élément sur un observableArray, mais uniquement si l'élément n'est pas déjà présent. Existe-t-il une fonction "find" ou un modèle recommandé pour y parvenir dans KnockoutJS?

J'ai remarqué que la fonction remove sur un observableArray peut recevoir une fonction permettant de transmettre une condition. Je veux presque la même fonctionnalité, mais ne poussez que si la condition transmise est ou n'est pas vraie.

102
jaffa

ObservableArray expose une fonction indexOf (wrapper to ko.utils.arrayIndexOf). Cela vous permet de faire:

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

Si les deux ne font pas réellement référence au même objet et que vous souhaitez exécuter une logique de comparaison personnalisée, vous pouvez utiliser ko.utils.arrayFirst comme:

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

if (!match) {
  myObservableArray.Push(itemToAdd);
}
222
RP Niemeyer

Merci RP. Voici un exemple d'utilisation de votre suggestion pour renvoyer la propriété 'name' via la propriété 'id' de l'objet à partir de mon modèle de vue.

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

En HTML, j'ai ce qui suit ($ parent est dû au fait qu'il se trouve dans une boucle de ligne de table):

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

recherche un objet dans 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
kamran

Je voudrais ajouter "valueWillMutate ()" avant les modifications et "valueHasMutated ()" après eux.

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();
}
0
Pavel Babiy