我只是想创建一些复选框和输入,从数据库中获取数据,并在编辑后将其保存回数据库。但是我得到以下错误:
未捕获类型错误:无法处理绑定"如果:function(){返回$root。editAlarmValues}";消息:无法处理绑定"启用:function(){返回$root.editAlarmValues().setAlarmValues()}"消息:$ root.editAlarmValues(…)。setAlarmValues不是一个函数
我不确定我做错了什么。我检查了控制台,值被正确映射到数组,但它们似乎没有绑定到视图。任何帮助将非常感激!
代码如下:
<!--ko if: $root.editAlarmValues -->
<div class="row">
<div class="col-md-6">
<input type="checkbox" data-bind="iCheck: $root.editAlarmValues().setAlarmValues" class="large-check"/>
</div>
</div>
<div class="row">
<div class="col-md-5 form-inline">
<input type="checkbox" data-bind="iCheck: $root.editAlarmValues().setOutputCurrentPPLowValue, enable: $root.editAlarmValues().setAlarmValues()" class="large-check"/>
<input type="text" id="OutputCurrentPPLowValue" data-bind="value: $root.editAlarmValues().outputCurrentPPLowValue, enable: $root.editAlarmValues().setOutputCurrentPPLowValue()" class="form-control" maxlength="30" />
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="pull-right">
<button type="button" class="btn btn-primary btn-flat" data-bind="event: {click: $root.editSave}">Save</button>
</div>
</div>
</div>
<!-- /ko -->
和脚本:
var AlarmsViewModel = function (wellID) {
function EditAlarms(setAlarmValues, setOutputCurrentPPLowValue, outputCurrentPPLowValue) {
var self = this;
self.setAlarmValues = ko.observable(setAlarmValues);
self.setOutputCurrentPPLowValue = ko.observable(setOutputCurrentPPLowValue);
self.outputCurrentPPLowValue = ko.observable(outputCurrentPPLowValue);
}
var self = this;
self.wellID = ko.observable(wellID);
self.editAlarmValues = ko.observableArray();
self.init = function () {
self.editAlarmInit();
};
self.editAlarmInit = function () {
APIHelper.getData("/api/alarmapi/EditAlarms?wellID=" + self.wellID(), self.editAlarmsCallback, "");
};
self.editAlarmsCallback = function (data) {
//Map results
var temp = $.map(data.result, function (item) {
return new EditAlarms(item.setAlarmValues, item.setOutputCurrentPPLowValue, item.outputCurrentPPLowValue);
});
self.editAlarmValues(temp);
};
self.editSave = function () {
var jsonData = ko.toJSON(self.editAlarmValues);
APIHelper.postData("/api/alarmapi/EditAlarmsPost", jsonData);
};
self.init();
};
var wellID = @ViewBag.WellID;
ko.bindingHandlers.iCheck = {
init: function (el, valueAccessor) {
var observable = valueAccessor();
$(el).on("ifChanged", function () {
observable(this.checked);
});
},
update: function (el, valueAccessor) {
var val = ko.utils.unwrapObservable(valueAccessor());
if (val) {
$(el).iCheck('check');
} else {
$(el).iCheck('uncheck');
}
}
};
var vm = new AlarmsViewModel(wellID);
ko.applyBindings(vm);
你不想要<!-- ko if: editAlarmValues -->
,你想要<!-- ko foreach: editAlarmValues -->
。当目标数组为空时,foreach
不会运行,因此基本上实现了相同的功能。
在foreach
中,绑定上下文是有问题的EditAlarms
对象,所以您应该直接引用它的属性(iCheck: setOutputCurrentPPLowValue
而不是iCheck: $root.editAlarmValues().setOutputCurrentPPLowValue
)。
还要考虑你的命名。EditAlarms
不是单个对象的好名字。前缀set...
应该指向一个设置某些内容的方法。在这个例子中,它只是一个可观察属性。setAlarmValues
应该被称为alarmValues
,因为它不是一个数组,它实际上可能应该被称为alarmValue
。等等。
<!-- ko foreach: editAlarmValues -->
<div class="row">
<div class="col-md-6">
<input type="checkbox" data-bind="iCheck: setAlarmValues" class="large-check">
</div>
</div>
<div class="row">
<div class="col-md-5 form-inline">
<input type="checkbox" class="large-check" data-bind="
iCheck: setOutputCurrentPPLowValue,
enable: setAlarmValues
">
<input type="text" id="OutputCurrentPPLowValue" class="form-control" maxlength="30" data-bind="
value: outputCurrentPPLowValue,
enable: setOutputCurrentPPLowValue
">
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="pull-right">
<button type="button" class="btn btn-primary btn-flat" data-bind="click: $root.editSave">Save</button>
</div>
</div>
</div>
<!-- /ko -->
修改JS代码(将绑定处理程序的定义移到顶部,不要嵌套视图模型)
ko.bindingHandlers.iCheck = {
init: function (el, valueAccessor) {
var observable = valueAccessor();
$(el).on("ifChanged", function () {
observable(this.checked);
});
},
update: function (el, valueAccessor) {
var val = ko.unwap(valueAccessor());
$(el).iCheck(val ? 'check' : 'uncheck');
}
};
function EditAlarms(setAlarmValues, setOutputCurrentPPLowValue, outputCurrentPPLowValue) {
this.setAlarmValues = ko.observable(setAlarmValues);
this.setOutputCurrentPPLowValue = ko.observable(setOutputCurrentPPLowValue);
this.outputCurrentPPLowValue = ko.observable(outputCurrentPPLowValue);
}
function AlarmsViewModel(wellID) {
var self = this;
self.wellID = ko.observable(wellID);
self.editAlarmValues = ko.observableArray();
self.editAlarmInit = function () {
APIHelper.getData("/api/alarmapi/EditAlarms?wellID=" + self.wellID(), function (data) {
var alarms = data.result.map(item => new EditAlarms(
item.setAlarmValues,
item.setOutputCurrentPPLowValue,
item.outputCurrentPPLowValue
));
self.editAlarmValues(alarms);
});
};
self.editSave = function () {
APIHelper.postData("/api/alarmapi/EditAlarmsPost", ko.toJSON(self.editAlarmValues));
};
self.editAlarmInit();
}
var vm = new AlarmsViewModel(@ViewBag.WellID);
ko.applyBindings(vm);