knockout.js - 如何有條件地推送可觀察數組中的項目?





(5)


我會在變化之前加上“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();
}

我想push一個新項目推送到observableArray ,但前提是該項目不存在。 KnockoutJS中是否有任何“查找”功能或推薦模式?

我注意到observableArray上的remove函數可以接收一個傳入條件的函數。 我幾乎想要相同的功能,但只有在傳入的條件是或者不是真時才會推送它。




一個observableArray公開一個indexOf函數(封裝到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);
}



搜索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/




謝謝RP。 這裡有一個使用你的建議來通過我的視圖模型中的對象的'id'屬性返回'name'屬性的例子。

    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>



從我對Knockout和Backbone的 (簡短) 比較

Knockout旨在為HTML和Model之間提供靈活,易用的模型綁定。 它的XAML / Silverlight / WPF就像它的實現和使用模式一樣(考慮到它的來源,這是有道理的)。 但是,Knockout不提供模型之外的指導或構造。 開發人員可以在模型和模型綁定之外構建結構良好的JavaScript應用程序。 這通常會導致開發人員沒有良好的JavaScript經驗,因為他們沒有意識到在使用Knockout時他們需要考慮良好的應用程序結構。 當然這個問題不是Knockout的錯誤。 在很多情況下,它只是缺乏對工具提供的內容的理解,或者如何構建大型JavaScript應用程序。

就個人而言,我不喜歡Knockout。 我不是MVVM模式的粉絲。 我更喜歡Backbone的方法,我花了大部分時間來處理它。 但是,我認為Knockout的“事實上的”觀點不適合大型應用程序是錯誤的。 您可以使用Knockout構建非常大,複雜且結構良好的應用程序。 但是你必須提供除數據綁定和模型之外的所有結構。







knockout.js