2013-05-02 2 views
5

Javascript 및 Knockout.js를 사용하여 웹 응용 프로그램에서 정수 배열을 편집해야합니다. 이 배열은 텍스트 상자에 바인딩되며 텍스트 상자의 값이 변경 될 때마다 배열이 업데이트됩니다. 그리고 업데이트되면 요소의 합이 계산됩니다.변경 사항 추적 - observableArray의 관찰 가능 요소

이것은 내 첫 번째 시도입니다 : http://jsfiddle.net/ZLs2A/0/. 그것의 작동하지 않습니다 (합계 값은 어떤 요소에 대한 새 값을 입력 할 때 업데이 트되지 않습니다). 그 때 observableArray는 항목을 삽입하거나 제거한 후에 만 ​​합계 함수를 트리거한다는 것을 알았습니다. 내 다음 시도

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

는 숫자 배열 관측 (http://jsfiddle.net/ZLs2A/1/)의 모든 요소를 ​​만드는 것이 었습니다. 그것은 다시는 작동하지 않았다.

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

내 마지막 시도는 관찰 가능한 속성 안에 요소의 값을 저장하는 새로운 클래스 (ArrayItem)를 만드는 것입니다. 이번에는 효과가있었습니다! (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()); 

그러나, 나는이 새로운 클래스 ArrayItem을 만들어야하고 싶지 않았다. 제거 할 수있는 방법이 있습니까? 예제 작업을 observable 요소가있는 observableArray (예 : 두 번째 시도)와 같이 사용하고 있습니까?

+2

[이 (? 가능 중복) 질문] (http://stackoverflow.com/questions/9510539/knockout-js-how-to-correctly-bind-an : 바이올린 참조 -observablearray), 기본적으로'ArrayItem' 생성자를 사용하는 최종 버전과 비슷한 방식으로 (그 함수를 바로 인라인합니다). 해답은 1 살입니다. 따라서 무언가가 바뀌었을 수도 있습니다 ... 그렇지 않다면 이미 자신의 질문에 답한 것 같습니다. – Jeroen

+0

Breeze.js와 Knockout.js의 통합에 대해 언급 할 가치가 있습니다. http://www.breezejs.com/ –

답변

2

녹아웃은 값을 추적하지 않지만 이벤트 키를 사용하거나 직접 값을 변경하고 업데이트 할 수 있습니다. 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의 저자는 대답
+0

IE11에서 작동하는 것처럼 보이지만 jsfiddle 예제의 합계는 Firefox 45.0.1의 텍스트 필드 값 변경시 업데이트되지 않습니다. – Stefan

관련 문제