2013-05-02 17 views
5

Javascript ve Knockout.js kullanarak bir web uygulamasında bir dizi tamsayı düzenlemeliyim. Bu dizi metin kutularına bağlanır ve herhangi bir metin kutusunun değeri değiştirildiğinde, dizi güncellenir. Ve güncellendiğinde, elemanların toplamı hesaplanır. Bu, benim ilk denemem: http://jsfiddle.net/ZLs2A/0/. Çalışmıyor (herhangi bir eleman için yeni bir değer yazarken toplam değer güncellenmiyor). Bu, gözlemlenebilir Farkın, sadece öğeleri ekledikten veya çıkardıktan sonra toplam işlevini tetikleyeceğini anladım. Bir sonraki girişimiİzleme değişiklikleri - gözlenebilir gözlemlenebilir öğeArray

<h4>Numbers</h4> 
<button data-bind="click: add">Add</button> 
<ul data-bind="foreach: numbers"> 
    <li> 
     <input data-bind="value: $data"></input> 
    </li> 
</ul> 
<span data-bind="text: sum"></span> 

function MyViewModel() { 
    var self = this; 

    self.numbers = ko.observableArray([ 
     1, 
     2, 
     3 
    ]); 

    self.sum = ko.computed(function() { 
     var items = self.numbers(); 
     var total = 0; 
     for (var i = 0; i < items.length; i++) { 
      total += parseInt(items[i]); 
     } 
     return total; 
    }); 

    self.add = function() { 
     var lastIndex = self.numbers().length - 1; 
     var lastValue = self.numbers()[lastIndex]; 
     self.numbers.push(lastValue + 1); 
    } 
} 

ko.applyBindings(new MyViewModel()); 

numaraları dizisi gözlemlenebilir (http://jsfiddle.net/ZLs2A/1/) her eleman yapmaktı. Yine işe yaramadı.

self.numbers = ko.observableArray([ 
    ko.observable(1), 
    ko.observable(2), 
    ko.observable(3) 
]); 

Benim son deneyin bir gözlemlenebilir özelliği içinde öğesinin değerini tutmak için yeni bir sınıf (ArrayItem) yaratıyordu. Bu sefer işe yaradı! (http://jsfiddle.net/ZLs2A/3/)

<h4>Numbers</h4> 
<button data-bind="click: add">Add</button> 
<ul data-bind="foreach: numbers"> 
    <li> 
     <input data-bind="value: value"></input> 
    </li> 
</ul> 
<span data-bind="text: sum"></span> 

function MyViewModel() { 
    var self = this; 

    self.numbers = ko.observableArray([ 
     new ArrayItem(1), 
     new ArrayItem(2), 
     new ArrayItem(3) 
    ]); 

    self.sum = ko.computed(function() { 
     var items = self.numbers(); 
     var total = 0; 
     for (var i = 0; i < items.length; i++) { 
      total += parseInt(items[i].value()); 
     } 
     return total; 
    }); 

    self.add = function() { 
     var lastIndex = self.numbers().length - 1; 
     var lastItem = self.numbers()[lastIndex]; 
     var newValue = parseInt(lastItem.value()) + 1; 
     self.numbers.push(new ArrayItem(newValue)); 
    } 
} 

function ArrayItem(value){ 
    var self = this; 
    self.value = ko.observable(value); 
} 

ko.applyBindings(new MyViewModel()); 

Ancak, bu yeni sınıf ArrayItem oluşturmak zorunda kalmak gibi değildi. Ondan kurtulmanın herhangi bir yolu var, bu da örnek çalışmanın sadece gözlemlenebilir bir dizi gözlemlenebilir unsura sahip olmasını sağlıyor (ikinci denemem gibi)?

+2

[bu (? Mümkün çoğaltmak) soru] (http://stackoverflow.com/questions/9510539/knockout-js-how-to-correctly-bind-an: keman bakın -observablearray), temelde bir 'ArrayItem' yapıcısı ile son halinize benzer bir şekilde (o sadece bu işlevin satır içi). Cevap bir yaşında, bu yüzden bu arada bir şey değişmiş olabilir ... Eğer değilse, zaten kendi sorunuza cevap vermişsinizdir. – Jeroen

+0

Diğer şeylerin arasında Değişim İzleme özelliğini ekleyen Knockout.js ile Breeze.js entegrasyonundan bahsedilmeye değer. http://www.breezejs.com/ –

cevap

2

Knockout değeri izlemeyecektir, ancak bir çözüm olarak, olay tuşlarını basabilir veya değerleri kendiniz değiştirebilir ve güncelleyebilirsiniz. http://jsfiddle.net/tkirda/ZLs2A/4/

function MyViewModel() { 
    var self = this; 

    self.numbers = ko.observableArray([ 
     1, 
     2, 
     3 
    ]); 

    self.onChange = function(val, e){ 
     var el = e.srcElement; 
     var newVal = parseInt(el.value); 
     var index = parseInt(el.getAttribute('data-index')); 
     self.numbers()[index] = newVal; 
     self.updateSum(); 
    } 

    self.sum = ko.observable(0); 

    self.updateSum = function() { 
     var items = self.numbers(); 
     var total = 0; 
     for (var i = 0; i < items.length; i++) { 
      total += parseInt(items[i]); 
     } 
     self.sum(total); 
    }; 

    self.updateSum(); 

    self.add = function() { 
     var lastIndex = self.numbers().length - 1; 
     var lastValue = self.numbers()[lastIndex]; 
     self.numbers.push(lastValue + 1); 
    } 
} 

ko.applyBindings(new MyViewModel()); 
KO yazarı cevap
+0

Bu IE11 ile çalışmak gibi görünüyor olsa da, jsfiddle örneğindeki toplam Firefox 45.0.1'deki metin alanındaki değerlerin değişikliklerinde güncellenmiyor – Stefan

İlgili konular