淘汰赛如何在儿童观察中设置价值

Knockout how do I set value in child observable

我正在尝试使用模板实现内联编辑。在我的视图模型上,我有一个方法:self.changeMode。我是从按钮单击事件(在模板内)触发的。传递给 changeMode 函数的数据参数包含预期数据,但我需要更改可观察对象。我该怎么做?

var MyViewModel = function (data) {
    var self = this;

    self.managingAgentId = ko.observable(data.managingAgentId);
    self.companyName = ko.observable(data.companyName);
    self.companyNumber = ko.observable(data.companyNumber);
    self.isActive = ko.observable(data.isActive);
    self.agents = ko.observableArray(data.agents);
    
    // Change to Edit or Display mode
    self.changeMode = function (data,event) {
        event.preventDefault();
        // => need to change mode here!
    };
}


$(function () {

        $.ajax({
            type: "GET",
            url: ma.Urls.LoadManagingAgent
        }).done(function (result) {
            $.each(result.agents, function (index, element) {
                element.mode = "display";
            });
            
            ko.applyBindings(new MyViewModel(result));
        }).error(function (response) {
            addMessage(response);
        });
    });
<script type="text/html" id="display">
    <td data-bind="text: managingAgentMemberId"></td>
    <td data-bind="text: applicationUser.userName"></td>
    <td data-bind="text: applicationUser.email"></td>
    <td data-bind="text: applicationUser.emailConfirmed"></td>
    <td data-bind="text: isActive"></td>
    <td>
        <button class="btn btn-success btn-sm" data-bind="click:$root.changeMode">
            <i class="fa fa-edit"></i>
            Edit
        </button>
    </td>
</script>

<script type="text/html" id="edit">
    <td data-bind="text: managingAgentMemberId"></td>
    <td data-bind="text: applicationUser.userName"></td>
    <td data-bind="text: applicationUser.email"></td>
    <td data-bind="text: applicationUser.emailConfirmed"></td>
    <td><input type="checkbox" data-bind="checked: isActive" /> </td>
    <td>
        <button class="btn btn-success btn-sm kout-update">
            <i class="fa fa-save"></i>
            Update
        </button>
        <button class="btn btn-danger btn-sm kout-cancel">
            <i class="fa fa-stop"></i>
            Cancel
        </button>
    </td>
</script>

规范解:

function Child(data) {
    var self = this;
    self.name = ko.observable();
    self.mode = ko.observable('display');
    ko.mapping.fromJS(data, Child.mapping, self);
}
Child.prototype.toggleMode = function () {
    this.mode(this.mode() === 'display' ? 'edit' : 'display');
};
Child.mapping = {
    // mapping rules, if applicable
};
function Parent(data) {
    var self = this;
    self.children = ko.observableArray();
    ko.mapping.fromJS(data, Parent.mapping, self);
}
Parent.mapping = {
    children: {
        create: function (options) {
            return new Child(options.data);
        }
    }
};

ko.applyBindings(new Parent({
    children: [
        {name: 'Child 1'}, {name: 'Child 2'}, {name: 'Child 3'}
    ]
}));
td:first-child {
    width: 200px;
}
button {
    width: 6em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>

<table>
    <tbody data-bind="foreach: children">
        <tr data-bind="template: mode"></tr>
    </tbody>
</table>

<script type="text/html" id="display">
    <td data-bind="text: name"></td>
    <td>
        <button data-bind="click: toggleMode">Edit</button>
    </td>
</script>

<script type="text/html" id="edit">
    <td><input data-bind="value: name"></td>
    <td>
        <button data-bind="click: toggleMode">Save</button>
    </td>
</script>