给定计算属性
vm.checkedValueCount = ko.computed(function(){
var observables = getCurrentValues(); //an array of ko.observable[]
return _.filter(observables, function(v) { return v() }).length;
});
Run Code Online (Sandbox Code Playgroud)
假设getCurrentValues()可以返回在代码中其他位置修改的不同可观察对象集(并且来自比observableArray更复杂的结构).
我需要checkedValueCount
随时更新
问题是,ko.computed
似乎记住了最后返回的值,并且只在依赖项更新时才更新.这处理第一种情况,但不处理后者.
我正在寻找的是一种强制checkedValueCount重新运行的方法.我可以使用的东西像:
changeCurrentValues();
vm.checkeValueCount.recalculate();
Run Code Online (Sandbox Code Playgroud)
最简单的说,鉴于我有
a = ko.computed(function() { return Math.random() })
Run Code Online (Sandbox Code Playgroud)
如何强制调用a()
两次以返回不同的值.
使用knockout时,使用只读计算的observable而不是简单函数有什么好处?
以下是viewmodel构造函数和html代码段,例如:
var ViewModel = function(){
var self = this;
self.someProperty = ko.observable("abc");
self.anotherProperty = ko.observable("xyz");
self.someComputedProperty = function(){
return self.someProperty() + self.anotherProperty();
};
};
<input data-bind="value: someProperty"/>
<input data-bind="value: anotherProperty"/>
<p data-bind="text: someComputedProperty()"></p>
Run Code Online (Sandbox Code Playgroud)
这里的一切似乎都像你期望的那样工作,所以我应该使用以下原因:
?var ViewModel = function(){
var self = this;
self.someProperty = ko.observable("abc");
self.anotherProperty = ko.observable("xyz");
self.someComputedProperty = ko.computed(function(){
return self.someProperty() + self.anotherProperty();
});
};
<input data-bind="value: someProperty"/>
<input data-bind="value: anotherProperty"/>
<p data-bind="text: someComputedProperty"></p>
Run Code Online (Sandbox Code Playgroud)
我注意到http://knockoutjs.com/documentation/computedObservables.html上的文档声明"...声明性绑定只是作为计算的observables实现",所以这是否意味着我需要在我的viewmodels中明确使用它们?
我想知道如何创建一个计算的可观察数组.
在我的视图模型中,我有2个可观察数组,我希望有一个计算的可观察数组,它只是两个数组的组合.
function ViewModel() {
var self = this;
self.listA= ko.observableArray([]);
self.listB = ko.observableArray([]);
self.masterList= //combine both list A and B
Run Code Online (Sandbox Code Playgroud) 我正在尝试将一个cookie包装在一个计算的observable中(后来我将变成一个protectedObservable),并且我对计算的observable有一些问题.我认为计算的observable的更改将广播到已绑定到它的任何UI元素.
我创造了以下小提琴
JavaScript:
var viewModel = {};
// simulating a cookie store, this part isnt as important
var cookie = function () {
// simulating a value stored in cookies
var privateZipcode = "12345";
return {
'write' : function (val) { privateZipcode = val; },
'read': function () { return privateZipcode; }
}
}();
viewModel.zipcode = ko.computed({
read: function () {
return cookie.read();
},
write: function (value) {
cookie.write(value);
},
owner: viewModel
});
ko.applyBindings(viewModel);?
Run Code Online (Sandbox Code Playgroud)
HTML:
zipcode:
<input …
Run Code Online (Sandbox Code Playgroud) 我在视图模型中有3个可观察变量,并希望输出到格式化值.但是,我不想为每个人编写计算方法,因为它们是相同的.重用代码的最佳方法是什么?谢谢.
我要实现的代码是:
this.formattedPrice = ko.computed({
read: function () {
return '$' + this.price().toFixed(2);
},
write: function (value) {
// Strip out unwanted characters, parse as float, then write the raw data back to the underlying "price" observable
value = parseFloat(value.replace(/[^\.\d]/g, ""));
this.price(isNaN(value) ? 0 : value); // Write to underlying storage
},
owner: this
});
Run Code Online (Sandbox Code Playgroud)
失败的例子是:Jsfiddle
谢谢,
我试图在另一个计算属性中使用计算属性,当我运行代码时,我在控制台中收到以下错误.
ko.computed
除非指定"写入"选项,否则无法将值写入a
function AppViewModel() {
var self = this;
self.firstName = ko.observable('rahul');
self.lastName = ko.observable('sharma');
self.fullName = ko.computed(function() {
return self.firstName() +' ' + self.lastName();
});
self.upperFullName = ko.computed(function() {
return self.fullName.toUpperCase();
});
}
// Activates knockout.js
ko.applyBindings(new AppViewModel());
Run Code Online (Sandbox Code Playgroud)
这里是html代码和js小提琴链接
<p><input data-bind="value: firstName"></p>
<p><input data-bind="value: lastName"></p>
<p><input data-bind="value: fullName"></p>
<p> <span data-bind="text: upperFullName"> </span> </p>
Run Code Online (Sandbox Code Playgroud) 我有一个对象数组,它们被连接到一个可挖掘的可观察数组中.我需要对这些数组应用排序,我遇到了一些有点令人困惑的行为.
我的第一次尝试涉及在foreach数据绑定中应用排序.
http://jsfiddle.net/wnfXV/
<ul data-bind="foreach: people.sort(function(l,r) { return l.name == r.name ? 0 : (l.name < r.name ? -1 : 1)})">
这会执行正确的排序,但我无法动态添加/删除数组中的元素并进行DOM更新.
如果我添加一组括号来访问底层JavaScript数组,一切正常.
<ul data-bind="foreach: people().sort(function(l,r) { return l.name == r.name ? 0 : (l.name < r.name ? -1 : 1)})">
根据我发现的一些SO答案,我最终为排序的数组创建了一个计算的observable. http://jsfiddle.net/wnfXV/2/
self.sortedPeople = ko.computed(function() {
return self.people().sort(function(l,r) {
return l.name == r.name ? 0 : (l.name < r.name ? -1 : 1);
});
});
Run Code Online (Sandbox Code Playgroud)
这也有效.而且我甚至不需要数据绑定到计算的observable,因为它立即执行.我可以适当地推送和删除数组项和DOM更新.
但是,如果我将代码更改为:
self.sortedPeople = ko.computed(function() {
return self.people.sort(function(l,r) {
return l.name == r.name ? …
Run Code Online (Sandbox Code Playgroud) 给出以下HTML/JS(http://jsfiddle.net/mgs_jsfiddle/gUhm2/)
<div data-bind="foreach: users">
<p data-bind="click: $root.onClick">
<span data-bind="text: id"></span>
<span data-bind="text: firstName"></span>
<span data-bind="text: $root.isSelected($data)"></span>
</p>
</div>
$(function() {
function ViewModel() {
var self = this;
self.users = [
{ id: 1, firstName: "Bob" },
{ id: 2, firstName: "David" },
{ id: 3, firstName: "Walter" }
];
self.selectedId = ko.observable(1);
self.isSelected = function(user) {
return user.id === self.selectedId() ? "YES" : "NO";
};
self.onClick = function(user) {
self.selectedId(user.id);
}
};
ko.applyBindings(new ViewModel());
});
Run Code Online (Sandbox Code Playgroud)
显示一个列表.通过单击一行,行的id将存储到selectedId
. …
我对ko.computed变量定义的延迟计算的行为解释有点困惑.
这样的计算变量可以用属性deferEvaluation:true定义,它应该将评估推迟到任何其他属性要求变量值的时刻(参见http://knockoutjs.com/documentation/computed-reference.html),
当通过extend({deferred:true})扩展常规ko.computed变量时,它会异步调用计算并推迟它,直到所有当前运行的"线程"结束(参见http://knockoutjs.com/documentation/deferred-updates.html) .
这两个设置听起来非常相似,但每个设置都完全不同.
任何人都可以向我确认我是对的,或者如果我弄错了解释差异吗?
是否有一种大致实现以下概念的好方法:
var computed = ko.computed(function() {
readSomeObservables(); //<-- if these change, notify computed
ko.stopCollectingDependencies();
readSomeMoreObservables(); //<-- if these change, do not notify computed
ko.resumeCollectingDependencies();
});
Run Code Online (Sandbox Code Playgroud)
我知道peek()
,但在这种情况下,计算机正在调用从外部模块提供的方法,并且如果这些方法碰巧涉及可观察对象,则设计要求它纯粹是偶然的.
我有一个解决方案,大致是这样做的:
window.setTimeout(function() {
readSomeMoreObservables();
}, 0);
Run Code Online (Sandbox Code Playgroud)
但由于显而易见的原因,这并不理想,并且在某些情况下会导致不良行为.
knockout.js ×10
javascript ×3
arrays ×1
deferred ×1
foreach ×1
formatted ×1
knockout-2.0 ×1
sorting ×1