我正在尝试使用模板实现内联编辑。在我的viewmodel上,我有一个方法:self.changeMode。我通过按钮单击事件(在模板内)触发此操作。传递给changeMode函数的data参数包含预期数据,但我需要更改observable。我该怎么做?
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>
答案 0 :(得分:2)
规范解决方案:
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>