Javascript $parent.myFunction未在KnockoutJs中将行作为参数返回
我第一次使用knockoutjs,试图获得一个任务列表,然后能够单击其中一个以弹出形式显示它。我遇到的问题是data bind=“click:$parent.edit”,它调用ToDoListViewModel/edit 当我第一次开始编写列表代码时,它会将当前行的todo对象作为第一个参数传入edit函数。在为我的添加/编辑弹出窗体添加第二个视图模型后,它不再以这种方式工作。调用$parent.edit仍然调用edit函数,但是现在它传入一个空对象{} 看起来我遇到了一些相互冲突的绑定问题,有什么想法吗 以下是html的待办事项列表:Javascript $parent.myFunction未在KnockoutJs中将行作为参数返回,javascript,knockout.js,knockout-2.0,Javascript,Knockout.js,Knockout 2.0,我第一次使用knockoutjs,试图获得一个任务列表,然后能够单击其中一个以弹出形式显示它。我遇到的问题是data bind=“click:$parent.edit”,它调用ToDoListViewModel/edit 当我第一次开始编写列表代码时,它会将当前行的todo对象作为第一个参数传入edit函数。在为我的添加/编辑弹出窗体添加第二个视图模型后,它不再以这种方式工作。调用$parent.edit仍然调用edit函数,但是现在它传入一个空对象{} 看起来我遇到了一些相互冲突的绑定问题,有
<table class="table table-striped table-hover" data-bind="visible: isVisible">
<thead>
<tr>
<th>To-Do</th>
<th>Estimate</th>
<th>Deadline</th>
@if (Model == null) { <th>Property</th> }
<th>Tenant</th>
<th style="display: none;">Assigned To</th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: todos">
<tr data-bind="visible: isVisible()">
<td><a class="pointer" title="Edit To-Do" data-bind="click: $parent.edit, text: Task"></a></td>
<td data-bind="text: FormattedAmount"></td>
<td data-bind="text: FormattedDueDate"></td>
<td data-bind="visible: $parent.showPropertyColumn, text: PropertyName"></td>
<td data-bind="text: TenantName"></td>
<td>
<div class="btn-group pull-right">
<a class="btn btn-primary pointer default-click-action" data-bind="click: $parent.markComplete">Mark Complete</a>
<button class="btn btn-primary dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
<ul class="dropdown-menu">
<li><a class="pointer" data-bind="click: $parent.edit">Edit To-Do</a></li>
<li><a class="pointer" data-bind="click: $parent.remove">Delete To-Do</a></li>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
一种可能的解决方案是更换:
data-bind="click: $parent.edit"
与
你不能把你的代码减少到最低限度来展示你的问题吗?可能在JSFIDLE>
function ToDoList () {
if(!(this instanceof arguments.callee))
return new arguments.callee();
var parent = this;
this.showCompleted = ko.observable(false);
this.tenantFilter = new PropertyTenantFilter();
this.viewModel = {
list: new ToDoListViewModel(),
form: new ToDoFormViewModel()
};
this.init = function () {
//get all tenants.
utils.block($("#grid-content"), "Loading");
this.tenantFilter.init(function () {
//initialize view model.
ko.applyBindings(this.viewModel);
//setup controls & events.
$("#dueDate").datepicker();
$("#listingId").change(this.tenantFilter.getByListing.bind(this.tenantFilter)).change();
} .bind(this));
};
function ToDoListViewModel() {
//init.
var self = this;
self.todos = ko.observableArray([]);
//computed.
self.showPropertyColumn = ko.computed(function () {
return $("#originalListingId").val().length == 0;
});
self.isVisible = ko.computed(function () {
return _.find(self.todos(), function (todo) { return todo.isVisible(); }) != null;
});
//operations.
self.add = function () {
//set form field values.
parent.viewModel.form.fill(new schemas.ToDo({}, parent));
//show popup.
$("#popup").modal("show");
};
self.edit = function (todo) {
console.debug("edit: " + JSON.stringify(todo));
//set form field values.
parent.viewModel.form.fill(todo);
//update tenants dropdown for selected listing.
parent.tenantFilter.getByListing();
//show popup.
$("#popup").modal("show");
};
self.markComplete = function (todo) {
parent.markComplete(todo);
};
self.remove = function (todo) {
var result = confirm("Are you sure that you want to delete this To-Do?");
if (result) {
//save changes.
utils.ajax(basePath + "properties/deletetodo",
{ id: todo.Id },
function (success) {
//refresh results.
self.todos.remove(todo);
//show result.
utils.showSuccess('The To-Do has been deleted successfully');
}
);
}
};
self.toggleShowCompleted = function () {
parent.showCompleted(!parent.showCompleted());
$("#showCompletedTodos").text(parent.showCompleted() ? "Show Active" : "Show Completed");
};
self.update = function (todo) {
var existingToDo = _.find(self.todos(), function (item) { return item.Id() == todo.Id(); });
existingToDo = todo;
};
//load todos from server.
utils.ajax(basePath + "properties/gettodos",
{ id: $("#originalListingId").val(), showCompleted: parent.showCompleted() },
function (results) {
var mappedTodos = $.map(results, function (item) { return new schemas.ToDo(item, parent); });
self.todos(mappedTodos);
$("#grid-content").unblock();
}
);
}
function ToDoFormViewModel() {
//init.
var self = this;
self.todo = ko.observable({});
utils.setupPopupForm(self.saved);
//operations.
self.fill = function (todo, isEdit) {
//set form field values.
self.todo = todo;
if (todo.Id()) {
//update tenants dropdown for selected listing.
parent.tenantFilter.getByListing();
}
//show popup.
$("#popup").modal("show");
};
self.save = function (todo) {
self.todo = todo;
$("#form").submit();
};
self.saved = function (result) {
var todo = new schemas.ToDo(result.todo, parent);
if (result.isInsert)
parent.viewModel.list.todos().push(todo);
else
parent.viewModel.list.update(todo);
utils.showSuccess("Your To-Do has been saved successfully.");
};
self.markComplete = function (todo) {
parent.markComplete(todo);
};
}
this.markComplete = function (todo) {
var result = confirm("Are you sure that you want to mark this To-Do complete?");
if (result) {
//save changes.
utils.ajax(basePath + "properties/marktodocomplete", {
id: todo.Id()
},
function () {
todo.IsComplete(true);
//show success.
utils.showSuccess('Your To-Do has been marked completed');
} .bind(this)
);
}
}
this.init();
}
data-bind="click: $parent.edit"
data-bind="click:$root.viewModel.list.edit"