ノックアウト ベースのアプリケーションを作成しようとしていますが、一見解決できない問題に遭遇しました。イベント オブジェクトのリストを操作するための UI を作成しています。イベント オブジェクトのリストは、イベント オブジェクトのテーブルを含むメイン ビューに表示され、メイン ビューで変更できるプロパティがいくつかあります。
しかし、イベント オブジェクトにはサブ配列などの複雑なデータが含まれるため、単一のイベント オブジェクトの詳細な編集を行うために、イベント オブジェクトのリストからモーダル ビューを開くことができるようにしたいと考えています。モーダル ビューはメイン ビューと同じページ内から実行されるため、両方のビューに同じデータ モデルを使用できます。
モーダル ビューで 1 つのイベント オブジェクトのプロパティを編集できますが、何らかの理由で変更がメイン ビューに反映されません。イベント配列を反復すると、問題の配列要素が変更されていることがわかります。配列 (監視可能な配列) で 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>