0

我正在尝试制作一个基于淘汰赛的应用程序,但我遇到了一个看似无法解决的问题:我正在制作一个用于操作事件对象列表的 UI。事件对象列表显示在主视图中,其中包含一个事件对象表,其中一些属性可以在主视图中更改。

但由于事件对象将包含复杂数据,如子数组等,我希望能够从事件对象列表中打开模式视图,以便对单个事件对象进行详细编辑。模态视图与主视图在同一页面内运行,因此我可以对两个视图使用相同的数据模型。

我可以在模态视图中编辑单个事件对象中的属性,但由于某种原因,这些更改不会反映在主视图中。当我迭代事件数组时,我可以看到有问题的数组元素已更改。我尝试在数组(这是一个可观察的数组)上执行 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>
4

2 回答 2

0

问题可能是因为您的event对象本身没有可观察的属性。尝试将事件定义更改为如下内容:

{
    event_type: ko.observable("accession"),
    foundation: ko.observable("Found")
}

您可能需要进行一些其他更改以说明这些属性现在是可观察的这一事实,但这意味着从一个位置对对象所做的更改将反映在其他位置。

于 2013-05-03T15:26:54.203 回答
0

您需要拥有的是具有可观察值的对象数组。那么你就不需要做任何额外的事情了。

如果您将演示放在http://jsfiddle.net/中会很有帮助

于 2013-05-03T15:27:25.860 回答