我想做一個基於敲除的應用程序,我遇到了一個看似不能解決的問題:我正在製作一個用於操作事件對象列表的UI。事件對象列表顯示在主視圖中,其中包含一個事件對象表,其中包含一些可在主視圖中更改的屬性。Knockout.js:改變數組元素的問題
但是,因爲事件對象將包含複雜數據,如子數組等,我希望能夠從事件對象列表中打開模式視圖,以便對單個事件對象進行詳細編輯。模態視圖與主視圖在同一頁面內運行,因此我可以爲兩個視圖使用相同的數據模型。
我能夠在模態視圖中的單個事件對象中編輯屬性,但由於某些原因,這些更改未反映在主視圖中。當我迭代事件數組時,我可以看到有問題的數組元素已被更改。我嘗試在數組(這是一個可觀察數組)上執行valueHasMutated方法,但這沒有效果。希望這裏有一些好的建議。我試着編譯一個自包含的HTML頁面,它比單詞更好地解釋了這個問題。但是恐怕代碼有點長。但在這裏它是無論如何: 淘汰賽測試
<form id="photograph-form">
<div class="row-fluid span12">
<h4>Events</h4>
<table class="table table-condensed table-hover span11 table-striped">
<thead>
<tr>
<th class="span1">Delete</th><th class="span1">Edit</th><th class="span1">Type</th><th class="span1">Dating basis</th>
</tr>
</thead>
<!-- Todo: Generate table body -->
<tbody data-bind="foreach: events">
<tr>
<td><a href="#" data-bind="click: $root.removeEvent"><i
class="icon-trash"></i></a></td>
<td><a data-bind="click: $root.setCurrentEvent" href="#eventView" role="button"
data-toggle="modal">
<i class="icon-edit"></i></a></td>
<td><select class="input-medium" data-bind="value: event_type,
options: event_types,
optionsValue: 'identifier',
optionsText: 'name'"></select></td>
<td><input class="input-medium" data-bind="value: foundation"/>
</td>
</tr>
</tbody>
</table>
</div>
</form>
<p>Current item foundation: <span data-bind="text: currentEvent().foundation"></span></p>
<div class="row-fluid">
<!-- Button to trigger modal -->
<a role="button" class="btn" data-toggle="modal" href="#eventView" data-bind="click: $root.addEvent">New</a>
</div>
<!-- Modal window -->
<div id="eventView" class="modal hide fade" tabindex="-1" role="dialog"
aria-labelledby="eventLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-hidden="true">×
</button>
<h3 id="eventLabel">Event</h3>
</div>
<div class="modal-body">
<label for="eventType">Event type</label>
<select id="eventType" class="input-medium" data-bind="value: currentEvent().event_type,
options: event_types,
optionsValue: 'identifier',
optionsText: 'name'"></select>
<label for="eventFoundation">Dating basis</label>
<input id="eventFoundation" class="input-medium"
data-bind="value: currentEvent().foundation"/>
</div>
<div class="modal-footer">
<button class="btn btn-primary" data-dismiss="modal"
aria-hidden="true" data-bind="click: $root.updateEvent">OK
</button>
</div>
</div>
<script src="js/jquery.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/knockout.js"></script>
<script>
var event_types = [
{ identifier: "accession", name: "Accession" },
{ identifier: "other", name: "Other" },
{ identifier: "ownership", name: "Ownership" }
];
var model = new ArtifactModel("photograph");
model.history_description = ko.observable();
model.events = ko.observableArray([
{ event_type: "accession", foundation: "Found"},
{ event_type: "ownership", foundation: "Museum"}
]);
model.currentEvent = ko.observable({ event_type: "accession", foundation: "Found"});
ko.applyBindings(model);
function ArtifactModel(artifact_type) {
var self = this;
self.artifact_id = ko.observable();
self.events = ko.observableArray();
self.currentEvent = ko.observable();
// Operations
self.addEvent = function() {
self.events.push({
event_type: "",
foundation: ""
});
self.currentEvent(self.events()[self.events().length - 1]);
};
self.setCurrentEvent = function(event) {
self.currentEvent(event);
console.log("Before: Event.foundation: " + self.currentEvent().foundation);
};
self.updateEvent = function(event) {
for (var t = 0 ; t < event.events().length ; t++) {
console.log("After: Event.foundation: " + event.events()[t].foundation);
}
event.events.valueHasMutated(); // No effect!
}
}
</script>
</body>
</html>
的潛在問題與此解決方案您的演示,是模型和事件陣列將首先使用Ajax來填充。我不確定是否有可能強加可觀察的財產。但我會試一試。謝謝! – 2013-05-06 07:54:07
建議的解決方案有效:編輯通過UI添加的事件時,使屬性可觀察。 至於由ajax調用產生的事件,似乎ko.mapping.fromJS方法自動將屬性設置爲可觀察的。 – 2013-05-06 08:28:48