วิธีการพุชรายการในอาร์เรย์ที่สังเกตได้ตามเงื่อนไข


103

ฉันต้องการpushไอเท็มใหม่ไปยัง an observableArrayแต่ถ้าไอเท็มนั้นยังไม่มีอยู่ มีฟังก์ชัน "ค้นหา" หรือรูปแบบที่แนะนำสำหรับการบรรลุสิ่งนี้ใน KnockoutJS หรือไม่?

ฉันสังเกตเห็นว่าremoveฟังก์ชันบนobservableArrayสามารถรับฟังก์ชันสำหรับการส่งผ่านในเงื่อนไข ฉันเกือบจะต้องการฟังก์ชันเดียวกัน แต่จะผลักดันก็ต่อเมื่อเงื่อนไขที่ส่งผ่านเป็นหรือไม่เป็นจริงเท่านั้น

คำตอบ:


223

ObservableArray แสดงindexOfฟังก์ชัน (wrapper to ko.utils.arrayIndexOf) สิ่งนี้ช่วยให้คุณทำ:

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

หากทั้งสองไม่ใช่การอ้างอิงถึงวัตถุเดียวกันและคุณต้องการเรียกใช้ตรรกะการเปรียบเทียบแบบกำหนดเองคุณสามารถใช้ko.utils.arrayFirstดังนี้:

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

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

สิ่งนี้ทำการเปรียบเทียบคุณสมบัติทั้งหมดใน itemToAdd หรือไม่ ฉันต้องการทดสอบคุณสมบัติ Id เท่านั้น
jaffa

5
สิ่งนี้จะตรวจสอบว่าทั้งสองเป็นวัตถุเดียวกัน ko.utils.arrayFirstหากคุณจำเป็นต้องตรวจสอบคุณสมบัติของบุคคลแล้วคุณสามารถใช้ ฉันจะเพิ่มตัวอย่างในคำตอบ
RP Niemeyer

4
เคล็ดลับที่ยอดเยี่ยม แต่ฉันต้องเปลี่ยน itemToAdd.id === item.id เป็น itemToAdd.id () === item.id () ฉันโพสต์รหัสของฉันในคำตอบถัดไป
Rake36

1
@ Rake36 สิ่งนี้จะขึ้นอยู่กับว่าคุณคิดว่ารหัสรายการของคุณจะเปลี่ยนไปหรือไม่และจำเป็นต้องสังเกตได้
Louis

1
@spaceman - คุณมีปัญหาอะไร ===? คุณมีตัวอย่างหรือไม่? คุณกำลังเปรียบเทียบสตริงกับตัวเลขหรืออะไร?
RP Niemeyer

11

ขอบคุณ RP. นี่คือตัวอย่างของการใช้คำแนะนำของคุณเพื่อส่งคืนคุณสมบัติ "name" ผ่านคุณสมบัติ "id" ของอ็อบเจ็กต์จากภายในโมเดลมุมมองของฉัน

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

ใน HTML ฉันมีสิ่งต่อไปนี้ ($ parent เนื่องจากสิ่งนี้อยู่ในลูปแถวตาราง):

<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

ค้นหาวัตถุใน 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

ฉันจะเพิ่ม "valueWillMutate ()" ก่อนการเปลี่ยนแปลงและ "valueHasMutated ()" ตามหลัง

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();
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.