带有模型的 Knockout 计算列
Knockout computed column with model
我的 MVC C# 解决方案中有一个具有以下 属性 的模型
public class RegistrationRequirementModel
{
public string LoadIntent { get; set; }
public string Francophone { get; set; }
public string Gender { get; set; }
public RegistrationRequirementModel(L09RegistrationRequirement requirement)
{
LoadIntent = requirement.LoadIntent;
Francophone = requirement.Francophone;
Gender = requirement.Gender;
}
}
在我的 javascript 中,我可以调用模型并显示数据,但是在使用某些计算函数时失败了。
Javascript
var registrationRequirementModel = {
frenchData: ko.observable(""),
genderData: ko.observable(""),
loadIntentData: ko.observable(""),
isMissingData: ko.computed(function () {
if (this.frenchData() == "") { return true };
if (this.genderData() == "") { return true };
if (this.loadIntentData() == "") { return true };
return false;
},this),
}
$(document).ready(function () {
ko.applyBindings(registrationRequirementModel, document.getElementById("RegistrationSurveyContent"));
$.ajax({
url: getStudentRegRequirementsUrl,
type: "GET",
contentType: jsonContentType,
dataType: "json",
success: function (data) {
if (!account.handleInvalidSessionResponse(data)) {
registrationRequirementModel.frenchData(data.Francophone);
registrationRequirementModel.genderData(data.Gender);
registrationRequirementModel.loadIntentData(data.LoadIntent);
}
},
error: function (jqXHR, textStatus, errorThrown) {
if (jqXHR.status != 0)
$('#notificationHost').notificationCenter('addNotification', { message: "Unable to retrieve registration requirement.", type: "error" });
}
});
});
Html
<table style="width:100%">
<tbody>
<tr>
<td data-bind="text: loadIntentData"></td>
<td data-bind="text: frenchData"></td>
<td data-bind="text: genderData"></td>
</tr>
</tbody>
</table>
目的是显示html是否有缺失数据。但是,当我激活此代码时,计算列一直说 frenchData 不是函数。我的观点可以用在我的htmldata-bind="visible: isMissingData"
。但不幸的是。我可以事件读取我的数据。
这是我给 api
的电话
public async Task<JsonResult> GetRegistrationRequirementAsync()
{
string StudentID = CurrentUser.PersonId;
try
{
var requirement = await ServiceClient.L09GetRegistrationRequirementAsync(StudentID);
RegistrationRequirementModel registrationRequirementModel = new RegistrationRequirementModel(requirement);
return Json(registrationRequirementModel, JsonRequestBehavior.AllowGet);
}
catch (Exception e)
{}
}
frenchData is not a function
控制台错误源于 KnockoutJS ViewModel 的设置方式。本质上,正常可观察对象下面的计算函数 isMissingData
有一个新的内部范围上下文 this
,它不反映 registrationRequirementModel
对象的相同外部范围。
要解决此问题,您应该从使用 object literal
切换到 constructor function
,这样您就可以将 this
ViewModel 范围分配给 self/that
变量,从而减轻范围问题。然后通过 KO Apply Bindings 实例化您新存储的 ViewModel,您现在可以在 AJAX 成功后访问它:
function registrationRequirementModel() {
var self = this;
self.frenchData = ko.observable("");
self.genderData = ko.observable("");
self.loadIntentData = ko.observable("");
self.isMissingData = ko.computed(function() {
if (self.frenchData() == "") {
return true
};
if (self.genderData() == "") {
return true
};
if (self.loadIntentData() == "") {
return true
};
return false;
}, this);
}
$(document).ready(function() {
var vm = new registrationRequirementModel();
ko.applyBindings(vm, document.getElementById("RegistrationSurveyContent"));
// replace with endpoint
var jsonData = {
Francophone: "Francophone",
Gender: "Male",
LoadIntent: "LoadIntent"
};
if (handleInvalidSessionResponse(jsonData)) {
vm.frenchData(jsonData.Francophone);
vm.genderData(jsonData.Gender);
vm.loadIntentData(jsonData.LoadIntent);
}
});
function handleInvalidSessionResponse(data) {
if (typeof data !== "undefined") return true;
return false;
}
下面是场景的模拟 JSFiddle
http://jsfiddle.net/ajxrw39m/3/
当您定义视图模型时,this
不指向新创建的对象,它指向您正在创建它的上下文中的任何 this
(可能 window
).
var vm = {
computedUsingThis: ko.computed(function() {
return this;
}, this)
}
console.log(
vm.computedUsingThis() === vm, // false
vm.computedUsingThis() === window // true
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
有很多方法可以规避这个问题。您可以使用构造函数和 new
关键字,或为视图模型创建工厂方法:
const VM = () => {
const a = ko.observable("a");
const b = ko.observable("b");
const ab = ko.pureComputed(
() => a() + b()
);
return { a, b, ab };
}
const vm = VM();
vm.ab.subscribe(console.log);
setTimeout(
() => {
vm.a("A");
},
500
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
我的 MVC C# 解决方案中有一个具有以下 属性 的模型
public class RegistrationRequirementModel
{
public string LoadIntent { get; set; }
public string Francophone { get; set; }
public string Gender { get; set; }
public RegistrationRequirementModel(L09RegistrationRequirement requirement)
{
LoadIntent = requirement.LoadIntent;
Francophone = requirement.Francophone;
Gender = requirement.Gender;
}
}
在我的 javascript 中,我可以调用模型并显示数据,但是在使用某些计算函数时失败了。
Javascript
var registrationRequirementModel = {
frenchData: ko.observable(""),
genderData: ko.observable(""),
loadIntentData: ko.observable(""),
isMissingData: ko.computed(function () {
if (this.frenchData() == "") { return true };
if (this.genderData() == "") { return true };
if (this.loadIntentData() == "") { return true };
return false;
},this),
}
$(document).ready(function () {
ko.applyBindings(registrationRequirementModel, document.getElementById("RegistrationSurveyContent"));
$.ajax({
url: getStudentRegRequirementsUrl,
type: "GET",
contentType: jsonContentType,
dataType: "json",
success: function (data) {
if (!account.handleInvalidSessionResponse(data)) {
registrationRequirementModel.frenchData(data.Francophone);
registrationRequirementModel.genderData(data.Gender);
registrationRequirementModel.loadIntentData(data.LoadIntent);
}
},
error: function (jqXHR, textStatus, errorThrown) {
if (jqXHR.status != 0)
$('#notificationHost').notificationCenter('addNotification', { message: "Unable to retrieve registration requirement.", type: "error" });
}
});
});
Html
<table style="width:100%">
<tbody>
<tr>
<td data-bind="text: loadIntentData"></td>
<td data-bind="text: frenchData"></td>
<td data-bind="text: genderData"></td>
</tr>
</tbody>
</table>
目的是显示html是否有缺失数据。但是,当我激活此代码时,计算列一直说 frenchData 不是函数。我的观点可以用在我的htmldata-bind="visible: isMissingData"
。但不幸的是。我可以事件读取我的数据。
这是我给 api
的电话 public async Task<JsonResult> GetRegistrationRequirementAsync()
{
string StudentID = CurrentUser.PersonId;
try
{
var requirement = await ServiceClient.L09GetRegistrationRequirementAsync(StudentID);
RegistrationRequirementModel registrationRequirementModel = new RegistrationRequirementModel(requirement);
return Json(registrationRequirementModel, JsonRequestBehavior.AllowGet);
}
catch (Exception e)
{}
}
frenchData is not a function
控制台错误源于 KnockoutJS ViewModel 的设置方式。本质上,正常可观察对象下面的计算函数 isMissingData
有一个新的内部范围上下文 this
,它不反映 registrationRequirementModel
对象的相同外部范围。
要解决此问题,您应该从使用 object literal
切换到 constructor function
,这样您就可以将 this
ViewModel 范围分配给 self/that
变量,从而减轻范围问题。然后通过 KO Apply Bindings 实例化您新存储的 ViewModel,您现在可以在 AJAX 成功后访问它:
function registrationRequirementModel() {
var self = this;
self.frenchData = ko.observable("");
self.genderData = ko.observable("");
self.loadIntentData = ko.observable("");
self.isMissingData = ko.computed(function() {
if (self.frenchData() == "") {
return true
};
if (self.genderData() == "") {
return true
};
if (self.loadIntentData() == "") {
return true
};
return false;
}, this);
}
$(document).ready(function() {
var vm = new registrationRequirementModel();
ko.applyBindings(vm, document.getElementById("RegistrationSurveyContent"));
// replace with endpoint
var jsonData = {
Francophone: "Francophone",
Gender: "Male",
LoadIntent: "LoadIntent"
};
if (handleInvalidSessionResponse(jsonData)) {
vm.frenchData(jsonData.Francophone);
vm.genderData(jsonData.Gender);
vm.loadIntentData(jsonData.LoadIntent);
}
});
function handleInvalidSessionResponse(data) {
if (typeof data !== "undefined") return true;
return false;
}
下面是场景的模拟 JSFiddle http://jsfiddle.net/ajxrw39m/3/
当您定义视图模型时,this
不指向新创建的对象,它指向您正在创建它的上下文中的任何 this
(可能 window
).
var vm = {
computedUsingThis: ko.computed(function() {
return this;
}, this)
}
console.log(
vm.computedUsingThis() === vm, // false
vm.computedUsingThis() === window // true
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
有很多方法可以规避这个问题。您可以使用构造函数和 new
关键字,或为视图模型创建工厂方法:
const VM = () => {
const a = ko.observable("a");
const b = ko.observable("b");
const ab = ko.pureComputed(
() => a() + b()
);
return { a, b, ab };
}
const vm = VM();
vm.ab.subscribe(console.log);
setTimeout(
() => {
vm.a("A");
},
500
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>