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.
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);
}
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>
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>
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();
}