我在淘汰赛和淘汰赛映射,CustomerViewModel,WorkOrderViewModel和RepairViewModel中设置了祖父母,父,子ViewModel关系。
我想在子项中设置一个子ko.computed值,该值在RepairViewModel中占用小时数,并在WorkOrderView模型中将其乘以Rate。
在RepairViewModel中我有这样的代码:
self.RepairCost = ko.computed(function () {
return (self.Hours() * self.parent.LabourChargeCost()).toFixed(2);
});
有没有办法获得父母的价值?
非常感谢!
以下是我使用(简化)的JS代码:
var workOrderMapping = {
'WorkOrders': {
key: function (workOrders) {
return ko.utils.unwrapObservable(workOrders.WorkOrderId);
},
create: function (options) {
return new WorkOrderViewModel(options.data);
}
},
'Repairs': {
key: function (repairs) {
return ko.utils.unwrapObservable(repairs.RepairId);
},
create: function (options) {
return new RepairViewModel(options.data);
}
}
};
RepairViewModel = function (data) {
var self = this;
ko.mapping.fromJS(data, workOrderMapping, self);
self.RepairCost = ko.computed(function () {
return (self.Hours() * self.parent.LabourChargeCost()).toFixed(2);
})
;
}
WorkOrderViewModel = function (data) {
var self = this;
ko.mapping.fromJS(data, workOrderMapping, self);
}
CustomerViewModel = function (data) {
var self = this;
ko.mapping.fromJS(data, workOrderMapping, self);
self.save = function () {
//alert(ko.toJSON(self));
$.ajax({
url: "/Customers/Save/",
type: "POST",
data: ko.toJSON(self),
contentType: "application/json",
success: function (data) {
//alert("succ");
//alert(data.customerViewModel);
// if (data.customerViewModel != null) {
//alert("succ2");
new PNotify({
title: 'Saved',
text: 'Record saved successfully',
type: 'success',
styling: 'bootstrap3'
});
ko.mapping.fromJS(data.customerViewModel, workOrderMapping, self);
if (data.newLocation != null)
window.location = data.newLocation;
},
});
};
}
答案 0 :(得分:0)
除非您将父级传递给子级并保留引用,否则您无法访问子级模型中的父级。
过去对我有用的是将值传递给子模型,然后在父级中添加subscribe以在更改值时更新子级。
function Parent(){
var self = this;
self.someValue = ko.obserable();//init if you need to
self.children = [new Child(self.someValue())]
self.someValue.subscribe(function(value){
for(var i = 0;i<self.children.length;i++){
self.children[i].parentValue(value);
}
});
}
function Child(value){
var self = this;
self.parentValue = ko.observable(value);
}
答案 1 :(得分:0)
不幸的是你无法做到这一点,它不是Knockout的限制,而是JS:你无法从对象属性中访问父上下文。
你可以做的是,正如@GrayTower所提到的那样,将你的父母作为参数传递给我,但这对我而言,感觉有点像黑客(我承认有时会使用它)。
您也可以在绑定视图模型之前,从父级内部或外部修改子视图模型。我并不真正了解您提供的代码中的属性流,但我希望更小的测试用例符合您的需求:http://jsfiddle.net/kevinvanlierde/507k237y/。假设我们有以下父子视图模型:
// symbolizes an employee
function ChildVM(name, hoursWorked) {
var self = this, parent;
this.name = name;
this.hoursWorked = hoursWorked;
}
// symbolizes a payment system
function MasterVM() {
var self = this;
this.rate = 25; // dollars/hour
this.employees = [
new ChildVM('Chris',16),
new ChildVM('Cagle',32)
];
}
var app = new MasterVM(),
view = document.getElementsByTagName('table')[0];
我们希望为payout
中的每个ChildVM
添加一个属性employees
,rate
将MasterVM
与hoursWorked
结合使用ChildVM
来自ko.computed
,即MasterVM
。您只需将一个函数粘贴到 ko.utils.arrayForEach(self.employees, function(i) {
i.payout = ko.computed(function() {
return i.hoursWorked*self.rate;
});
});
构造函数中,如下所示:
ko.applyBindings
或者您可以在调用 this.initEmployees = function() {
ko.utils.arrayForEach(self.employees, function(i) {
i.payout = ko.computed(function() {
return i.hoursWorked*self.rate;
});
});
}
app.initEmployees();
ko.applyBindings(app, view);
之前将其设为方法并调用它:
applyBindings
或者您甚至可以构建一个callbacks
包装器,它在绑定视图和模型之前执行'callBefore'(cf。&lt; =&gt; AJAX function initVM(VM, callbefore, element) {
callbefore(VM);
ko.applyBindings(VM, element);
}
initVM(app, function(vm) {
ko.utils.arrayForEach(vm.employees, function(i) {
i.payout = ko.computed(function() {
return i.hoursWorked*vm.rate;
});
});
},view);
),如下所示:
ko.mapping.fromJS
<强> fiddle 强>
注意:使用{{1}}将所有值转换为observable,而当您的值不需要更新时,您不需要observable,您可以使用纯JS值/ objects。