使用ko.computed和if语句来设置对象的可观察属性
use ko.computed with if statement to set object observable property
刚刚开始使用knockout和javascript。我一直在设置对象monthData的mPrice值。
function monthData(mYear, mMonth, mSS, mMs, mLimit, mPerItem, mStartingPrice) {
var self = this;
self.mYear= mYear;
self.mMonth = mMonth;
self.mSs = mSS;
self.mMs = mMs;
self.mTotal = mSS + mMs;
self.mLimit = mLimit;
self.mPerItem = mPerItem;
self.mStartingPrice = mStartingPrice;
};
这是因为它停止了工作。如果我设置self.mPrice=0,我至少会打印出所有月份。
self.mPrice = ko.computed(function() {
var limit = self.mLimit;
var perItem = self.mPerItem;
var startingPrice = self.mStartingPrice;
var total = self.mTotal;
if (total <= limit) {
return startingPrice;
} else {
var aboveLimit = total - limit;
var extra = aboveLimit * perItem;
return startingPrice + extra;
}
});
}
function statViewModel() {
this.tak = ko.observable(100);
this.styckpris = ko.observable(10);
this.grundpris = ko.observable(500);
var self = this;
// testing with some months
self.allMonths = ko.observableArray([
new monthData(2013, 1, 412, 142, this.tak, this.styckpris, this.grundpris),
new monthData(2013, 1, 412, 142, this.tak, this.styckpris, this.grundpris),
new monthData(2013, 1, 412, 142, this.tak, this.styckpris, this.grundpris),
new monthData(2013, 1, 412, 142, this.tak, this.styckpris, this.grundpris),
new monthData(2013, 1, 412, 142, this.tak, this.styckpris, this.grundpris)
]);
}
-编辑:就在我发帖后,我发现了一个失踪的超自然现象。现在我把它打印出来,但上面写着:
function d(){if(0<arguments.length){if(!d.equalityComparer||!d.equalityComparer(c,arguments[0]))d.H(),c=arguments[0],d.G();return this}b.r.Va(d);return c}NaN
Html:
<p>Tak: <input data-bind="value: tak" /></p>
<p>Styckpris: <input data-bind="value: styckpris" /></p>
<p>Grundpris: <input data-bind="value: grundpris" /></p>
<table>
<thead>
<tr>
<th>År</th><th>Månad</th><th>SS</th><th>MS</th><th>Total</th><th>Pris</th>
</tr>
</thead>
<tbody data-bind="foreach: allMonths">
<tr>
<td><span data-bind="text: mYear"></span></td>
<td><span data-bind="text: mMonth"></span></td>
<td><span data-bind="text: mSs"></span></td>
<td><span data-bind="text: mMs"></span></td>
<td><span data-bind="text: mTotal"></span></td>
<td><span data-bind="text: mPrice"></span></td>
</tr>
</tbody>
</table>
仅使用observableArray
"询问"敲除来"观察"阵列功能,即push
的创建、移除、移动项目等。
要"要求"knocket观察该数组中的对象,实际上需要它观察对象的特定属性。
因此,您的monthData
对象应该声明observable
s,而不是常规/基元属性:
function monthData(mYear, mMonth, mSS, mMs, mLimit, mPerItem, mStartingPrice) {
var self = this;
self.mYear = mYear;
self.mMonth = mMonth;
self.mSs = mSS;
self.mMs = mMs;
self.mTotal = ko.observable( mSS + mMs );
self.mLimit = ko.observable( mLimit );
self.mPerItem = ko.observable( mPerItem );
self.mStartingPrice = ko.observable( mStartingPrice );
...
}
注意,我只选择了最后4个作为observable
,因为这些是您在computed
中使用的属性。既然它们是observable
,那么当它们中的任何一个发生变化时,computed
将知道要重新评估。
此外,如果您希望self.mTotal
自动更新(即,如果您期望self.mSs
或self.mSm
更改(,则需要是computed
而不是observable
。
编辑:
不要忘记使用()
附加对这些变量的任何引用。您的计算机现在应该看起来像:
self.mPrice = ko.computed(function() {
var limit = self.mLimit();
var perItem = self.mPerItem();
var startingPrice = self.mStartingPrice();
var total = self.mTotal();
if (total <= limit) {
return startingPrice;
} else {
var aboveLimit = total - limit;
var extra = aboveLimit * perItem;
return startingPrice + extra;
}
});
编辑2:
很抱歉没有正确阅读问题。
我没有意识到你是用tak
、styckpris
和grundpris
通过的——当我的大脑看到另一种语言时,它可能已经关闭了:p
问题
因此,当将它们传递给monthData
构造函数时,您所做的就是取消引用它们。您已将值传递给可观测值,而不是传递给可观察值。通过传递该值,您的monthData
构造函数,以及由此计算的mPrice
,将无法看到可观察到的变化。
解决方案
将可观察性传递到构造函数中,而不取消对它们的引用。
function monthData(mYear, mMonth, mSS, mMs, mLimit, mPerItem, mStartingPrice) {
var self = this;
self.mYear= mYear;
self.mMonth = mMonth;
self.mSs = mSS;
self.mMs = mMs;
self.mTotal = mSS + mMs;
/* Remember that these are observable! */
self.mLimit = mLimit;
self.mPerItem = mPerItem;
self.mStartingPrice = mStartingPrice;
self.mPrice = ko.computed(function() {
/* So, remember to dereference them! */
var limit = self.mLimit();
var perItem = self.mPerItem();
var startingPrice = self.mStartingPrice();
var total = self.mTotal;
if (total <= limit) {
return startingPrice;
} else {
var aboveLimit = total - limit;
var extra = aboveLimit * perItem;
return startingPrice + extra;
}
});
}
function statViewModel() {
this.tak = ko.observable(100);
this.styckpris = ko.observable(10);
this.grundpris = ko.observable(500);
var self = this;
// testing with some months
self.allMonths = ko.observableArray([
new monthData(2013, 1, 412, 142, this.tak, this.styckpris, this.grundpris),
new monthData(2013, 1, 412, 142, this.tak, this.styckpris, this.grundpris),
new monthData(2013, 1, 412, 142, this.tak, this.styckpris, this.grundpris),
new monthData(2013, 1, 412, 142, this.tak, this.styckpris, this.grundpris),
new monthData(2013, 1, 412, 142, this.tak, this.styckpris, this.grundpris)
]);
}
请忽略我的另一个答案。我对你原来问题中的代码和你发布的答案感到困惑。所以我的解释不清楚。因此,在这里,我将回答您的问题,而不使用答案中的任何内容。
您接收时发生的错误
function d(){if(0<arguments.length){if(!d.equalityComparer||!d.equalityComparer(c,arguments[0]))d.H(),c=arguments[0],d.G();return this}b.r.Va(d);return c}NaN
可以简化为
<ko.observable>NaN
并且可以理解为:"可观察的不是数字">
这表明您正在尝试对可观察对象执行数学运算。
在您的if
语句中,您有:if(total <= limit)
。如果一个数字(total
(小于或等于(<=
(,则无法与可观测值(limit
(进行比较。您必须通过像函数一样调用limit来获得它的值。
你的计算结果现在应该是这样的:
self.mPrice = ko.computed(function() {
var limit = self.mLimit();
var perItem = self.mPerItem();
var startingPrice = self.mStartingPrice();
var total = self.mTotal;
if (total <= limit) {
return startingPrice;
} else {
var aboveLimit = total - limit;
var extra = aboveLimit * perItem;
return startingPrice + extra;
}
});
只有前3行需要更改-在这方面做一些小更改。没有别的。
编辑-这现在正按照我想要的工作
function monthData(mYear, mMonth, mSS, mMs, parent) {
var self = this;
self.mYear = mYear;
self.mMonth = mMonth;
self.mSs = mSS;
self.mMs = mMs;
self.mTotal = mSS + mMs;
self.mPrice = ko.computed(function () {
var limit = parent.tak();
var perItem = parent.styckpris();
var startingPrice = parent.grundpris();
var total = self.mTotal;
if (total <= limit) {
return startingPrice;
} else {
var aboveLimit = total - limit;
var extra = aboveLimit * perItem;
var sum = parseInt(startingPrice) + parseInt(extra);
return sum;
}
});
}
function statViewModel() {
var self = this;
self.tak = ko.observable(100);
self.styckpris = ko.observable(10);
self.grundpris = ko.observable(500);
// testing with some months
self.allMonths = ko.observableArray([
new monthData(2013, 1, 412, 142, self),
new monthData(2013, 2, 112, 642, self),
new monthData(2013, 2, 100, 742, self),
new monthData(2013, 3, 6513, 69, self),
new monthData(2013, 4, 34, 211, self),
new monthData(2013, 5, 123, 435, self),
new monthData(2013, 6, 412, 142, self),
new monthData(2013, 7, 412, 142, self)
]);
}
// Activates knockout.js
ko.applyBindings(new statViewModel());
- 将js对象更改为使用嵌套的可观察数组敲除js视图模型
- $scope$观察数组中的一个特定对象——Angular JS控制器
- 无法观察Ember.js中的对象数组
- 如何从具有动态可观察属性的淘汰对象中获取 JSON 字符串
- 培根.js Bus.plug: 未捕获 错误: 不是可观察的 : [对象对象]
- 使用rxjs创建一个可观察的对象,该对象稍后将连接到web套接字
- 将$scope对象作为参数提供给$digest中的观察者背后的逻辑
- Knockoutjs当父对象's可观察到的变化
- 在ko.applyBindings(..)中执行Knockout js订阅函数(用于可观察对象)
- 聚合物通过父对象观察子属性
- Knockoutjs观察嵌套对象并订阅更改
- Knockout.js用单个json对象绑定一个可观察对象
- 使用AngularJS观察整个对象(深度观察)
- 无限循环当观察父对象时,观察者不更新任何值
- 向KO传递在对象内可观察到的计算值
- 根据某些条件将 JS 绑定到可观察对象内的数组元素
- 如何从下拉列表中由可观察数组填充的选定项中检索完整对象
- 如何创建挖空可观察数组/对象的深层副本
- 对象.观察顺序
- 对象.观察同步回调