这是我用来绑定文本框的代码:
var CategoryViewModel = {
categoryModel: ko.observable({
categoryId: ko.observable(),
categoryName: ko.observable(),
active: ko.observable()
}),
GetCategoryById: function (data, event) {
CategoryViewModel.ClickId(event.target.id);
var ajaxUrl = ApplicationRootUrl("GetCategoryById", "Category") + "/" + CategoryViewModel.ClickId();
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
url: ajaxUrl,
dataType: "json",
success: function (data) {
if (data.isSuccess) {
// This value got bind to textbox
CategoryViewModel.categoryModel(data.data);
}
},
error: function (err) {
}
});
},
CategoryAddButton: function() {
CategoryViewModel.categoryModel();
$('#addCategoryModel').modal('toggle');
}
};
$(document).ready(function () {
ko.applyBindings(CategoryViewModel, document.getElementById("categoryMain"));
});
点击按钮时调用CategoryAddButton
方法。我试图在此方法中清空模型值。
这是HTML:
<input type="text" name="CategoryName" class="form-control" placeholder="Enter Category Name" data-bind="textinput: categoryModel().categoryName">
文本框值在ajax调用上绑定。但是,在调用CategoryAddButton
方法之后,该值不会绑定到文本框。
答案 0 :(得分:3)
首先,我建议您使用不同的方法从您编写的内容创建视图模型。尽管一些初学者的例子也是如此,但这只是为了简单起见 - 实际上,将视图模型创建为对象文字往往不是一个好主意。这是因为在许多其他重复项中发布了here,here和here,访问同一对象的另一个属性可能会非常脏,尽管该任务应该是多么微不足道。
因此,为了解决这个问题,你应该使用构造函数和new
运算符,因为这样可以更容易地操作对象。但是,我添加此内容仅作为编写更清晰代码的指南,使用构造函数和new
对象语法不能单独解决问题。
让我们回到你的问题。要找出代码不起作用的原因,请查看绑定工作时如何操作数据以及何时不工作。
你说在AJAX调用成功后,值得到了正确的更新,因此绑定工作正常。这是因为在AJAX调用的success
回调中,您实际上是将对象传递给categoryModel
。但是,我会指出你传递给它的不是一个可观察但只是一个普通的对象,而你最初创建它的属性是可观察的!所以即使在那里你也可能遇到问题。
您还说过点击按钮后,该值未更新。我不确定你在这里想要达到什么目标;您想要显示什么以及数据来自何处?因为你编写了这行代码:
CategoryViewModel.categoryModel();
只是一个吸气剂 - 它不会以任何方式改变物体,你只是在读它的价值。没有实际修改它,当然什么都不会改变。
所以,我会给你一个实现整个事情的可能方法,我建议你阅读更多关于javascript对象构造函数以及如何使用它们正确使用knockout。
function categoryViewModel() {
var self = this;
// Don't wrap these in another observable, that's totally needless.
this.categoryId = ko.observable(null);
this.categoryName = ko.observable(null);
this.active = ko.observable(true);
// You could actually define this on the prototype
// but I don't want to make it even more complicated
this.GetCategoryById = function(categoryId) {
// You could do this if the value passed can either be a plain value
// or an observable; ko will return the actual value to you.
var catId = ko.utils.unwrapObservable(categoryId);
var ajaxUrl = ApplicationRootUrl("GetCategoryById", "Category") + "/" + catId;
$.ajax({
type: 'GET',
contentType: "application/json; charset=utf-8",
url: ajaxUrl,
dataType: "json",
success: function(data) {
if (data.isSuccess) {
// Correct the object references according to
// the structure of the response if needed.
self.categoryId(data.data.id);
self.categoryName(data.data.name);
self.active(data.data.isActive);
}
},
error: function(err) {
}
});
};
this.CategoryAddButton = function() {
self.categoryId(null);
self.categoryName(null);
self.isActive(true); // If you want to default to true.
$('#addCategoryModel').modal('toggle');
};
};
$(document).ready(function () {
ko.applyBindings(new categoryViewModel(), document.getElementById("categoryMain"));
});
您的HTML可能是:
<input type="text" name="CategoryName" class="form-control" data-bind="textInput: categoryName" />
对于GetCategoryById
函数,如果将其分配给函数原型,而不是为创建的每个对象分配“副本”,它甚至会更好。但是因为我假设你只有1个你的viewmodel实例,所以我现在认为它超出了范围。