knockoutjs 数据绑定隐藏字段值
knockoutjs data bind hidden field value
我在挖空模板中有一个隐藏字段,它的值用 jquery 更新。问题是当尝试使用 ajax 将此值传递给服务器时,我在控制器中得到空值。但是 html 源代码显示隐藏字段的值已更新。如果我用文本框替换隐藏字段,只有在我手动输入文本时它才能正常工作。
jQuery
function getFileDetail(fileID, fileName) {
$('#hdnFileName' + fileID).val(fileName);
$('#lblFileName' + fileID).text(fileName);
}
这里是html淘汰模板:
<script type="text/html" id="fileTemplate">
<div data-role="fieldcontain">
<a href="#" data-bind="click: function () { openFileUpload('file', ID) }"><label data-bind="text: 'File Upload ' + ID, attr: { id: 'lblFileName' + ID }"></label></a><input type="button" value="Remove" data-bind="click: removeFile" />
</div>
<input type="hidden" name="hdnFileName" data-bind="attr: { id: 'hdnFileName' + ID, value: fileName }" />
</script>
视图模型
function FileViewModel() {
var self = this;
self.ID = ko.observable();
self.fileName = ko.observable();
self.removeFile = function (file) { };
self.Files = ko.observableArray([{ ID: 1, fileName: "", removeFile: function (file) { self.Files.remove(file); }}]);
self.addNewFile = function () {
var newFile = new FileViewModel();
newFile.ID = self.Files().length + 1;
newFile.fileName = "";
newFile.removeFile = function (file) { self.Files.remove(file); };
self.Files.push(newFile);
//$("input[name='hdnFileName'").trigger("change");
}
}
function ViewModel() {
var self = this;
self.fileViewModel = new FileViewModel();
self.submitForm = function () {
$.ajax({
type: "POST",
url: "<%= Url.Action("MeetingPresenter")%>",
data: "{Files:" + ko.utils.stringifyJson(self.fileViewModel.Files) + "}",
contentType: "application/json",
success: function (data) {},
});
};
}
您的模型 属性 ID
是可观察的,因此您需要 'unwrap' 在连接时从中获取值,如下所示:
<input type="hidden" name="hdnFileName" data-bind="attr: { id: 'hdnFileName' + ID(), value: fileName }" />
还有这个:
<label data-bind="text: 'File Upload ' + ID(), attr: { id: 'lblFileName' + ID() }"></label>
在我看来,通过 DOM 设置字段值不会与剔除交互。如果您使用 .value
设置其值,则不会更新可观察对象。您应该更新可观察对象。
我写了一点Fiddle来演示一下。每 2 秒,它通过 DOM 设置输入的值,但绑定的可观察值仅在您键入内容时更改。
var viewModel = (function () {
return {
fv: ko.observable().extend({notify:'always'})
};
}());
ko.applyBindings(viewModel);
setInterval(function () {
console.debug("Set it");
var f = document.getElementById('field');
f.value = "Hi";
console.debug("fv is", viewModel.fv());
}, 2000);
如果您正在使用 knockout.js
,则不需要修改 DOM,您只需更新 ViewModel
,DOM 将根据
function getFileDetail(fileID, fileName) {
viewModel.fileViewModel.update(fileID, fileName);
}
在FileViewModel
中添加update
功能
function FileViewModel() {
// rest of the code
self.update = function(fileID, fileName) {
var file = ko.utils.arrayFirst(self.Files(), function(file) {
return file.ID == fileID;
});
file.fileName(fileName); // this will change and the UI will be updated according
};
}
注意:请注意,您在 Files
中有一个默认项目,不会用 update
函数更改,因为属性不是 observable
self.Files = ko.observableArray([{ ID: 1, fileName: "", removeFile: function (file) { self.Files.remove(file); }}]);
您可以通过将它们设为 observable
(即 ID: observable(1)
)来解决此问题,或者您可以创建一个 new FileViewModel()
.
注意: viewModel
必须在函数中可访问(即全局实例),否则将是 undefined
.
我遇到了一个类似的问题,我需要在没有用户输入的情况下设置一个值。
在执行点击更新功能之前,我会执行所需的模型更新。如果有模式操作最好在模型中引入一个函数。
<input data-bind="click: function(){ isEnabled(true); update() }" />
我实际做的是,
<input data-bind="click: function(){ isEnabled(!isEnabled()); update() }" />
请记住 javascript 的异步性质。
我在挖空模板中有一个隐藏字段,它的值用 jquery 更新。问题是当尝试使用 ajax 将此值传递给服务器时,我在控制器中得到空值。但是 html 源代码显示隐藏字段的值已更新。如果我用文本框替换隐藏字段,只有在我手动输入文本时它才能正常工作。
jQuery
function getFileDetail(fileID, fileName) {
$('#hdnFileName' + fileID).val(fileName);
$('#lblFileName' + fileID).text(fileName);
}
这里是html淘汰模板:
<script type="text/html" id="fileTemplate">
<div data-role="fieldcontain">
<a href="#" data-bind="click: function () { openFileUpload('file', ID) }"><label data-bind="text: 'File Upload ' + ID, attr: { id: 'lblFileName' + ID }"></label></a><input type="button" value="Remove" data-bind="click: removeFile" />
</div>
<input type="hidden" name="hdnFileName" data-bind="attr: { id: 'hdnFileName' + ID, value: fileName }" />
</script>
视图模型
function FileViewModel() {
var self = this;
self.ID = ko.observable();
self.fileName = ko.observable();
self.removeFile = function (file) { };
self.Files = ko.observableArray([{ ID: 1, fileName: "", removeFile: function (file) { self.Files.remove(file); }}]);
self.addNewFile = function () {
var newFile = new FileViewModel();
newFile.ID = self.Files().length + 1;
newFile.fileName = "";
newFile.removeFile = function (file) { self.Files.remove(file); };
self.Files.push(newFile);
//$("input[name='hdnFileName'").trigger("change");
}
}
function ViewModel() {
var self = this;
self.fileViewModel = new FileViewModel();
self.submitForm = function () {
$.ajax({
type: "POST",
url: "<%= Url.Action("MeetingPresenter")%>",
data: "{Files:" + ko.utils.stringifyJson(self.fileViewModel.Files) + "}",
contentType: "application/json",
success: function (data) {},
});
};
}
您的模型 属性 ID
是可观察的,因此您需要 'unwrap' 在连接时从中获取值,如下所示:
<input type="hidden" name="hdnFileName" data-bind="attr: { id: 'hdnFileName' + ID(), value: fileName }" />
还有这个:
<label data-bind="text: 'File Upload ' + ID(), attr: { id: 'lblFileName' + ID() }"></label>
在我看来,通过 DOM 设置字段值不会与剔除交互。如果您使用 .value
设置其值,则不会更新可观察对象。您应该更新可观察对象。
我写了一点Fiddle来演示一下。每 2 秒,它通过 DOM 设置输入的值,但绑定的可观察值仅在您键入内容时更改。
var viewModel = (function () {
return {
fv: ko.observable().extend({notify:'always'})
};
}());
ko.applyBindings(viewModel);
setInterval(function () {
console.debug("Set it");
var f = document.getElementById('field');
f.value = "Hi";
console.debug("fv is", viewModel.fv());
}, 2000);
如果您正在使用 knockout.js
,则不需要修改 DOM,您只需更新 ViewModel
,DOM 将根据
function getFileDetail(fileID, fileName) {
viewModel.fileViewModel.update(fileID, fileName);
}
在FileViewModel
update
功能
function FileViewModel() {
// rest of the code
self.update = function(fileID, fileName) {
var file = ko.utils.arrayFirst(self.Files(), function(file) {
return file.ID == fileID;
});
file.fileName(fileName); // this will change and the UI will be updated according
};
}
注意:请注意,您在 Files
中有一个默认项目,不会用 update
函数更改,因为属性不是 observable
self.Files = ko.observableArray([{ ID: 1, fileName: "", removeFile: function (file) { self.Files.remove(file); }}]);
您可以通过将它们设为 observable
(即 ID: observable(1)
)来解决此问题,或者您可以创建一个 new FileViewModel()
.
注意: viewModel
必须在函数中可访问(即全局实例),否则将是 undefined
.
我遇到了一个类似的问题,我需要在没有用户输入的情况下设置一个值。 在执行点击更新功能之前,我会执行所需的模型更新。如果有模式操作最好在模型中引入一个函数。
<input data-bind="click: function(){ isEnabled(true); update() }" />
我实际做的是,
<input data-bind="click: function(){ isEnabled(!isEnabled()); update() }" />
请记住 javascript 的异步性质。