Not understanding ko.obseravables
Not understanding ko.obseravables
因此,请考虑以下内容:
(function($, ko){
var ViewModel = function() {
var self = this;
self.errorMessages = ko.observableArray([]);
self.desigItems = ko.observableArray([]);
self.frequencies = ko.observableArray([]);
}
var viewModel = new ViewModel();
var loadData = function() {
$.ddcApiGet('/widget/desigs.json', [], function(data) {
_processLoadedData(data);
}, viewModel.errorMessages);
}
var loadFrequencies = function() {
$.ddcApiGet('/widget/freqs.json', [], function(data) {
_processFrequenciesData(data);
}, viewModel.errorMessages);
}
var _processLoadedData = function(data) {
for (var i = 0; i < data.desig_options.length; i++) {
viewModel.desigItems.push(data.desig_options[i]);
}
}
var _processFrequenciesData = function(data) {
var frequencies = [];
// Get the list of frequencies.
for (var i = 0; i < data.frequency.length; i++) {
frequencies.push(data.frequency[i]);
}
// Push frequencies on to each of the design items in the list.
for (var i = 0; i < viewModel.desigItems.length; i++) {
viewModel.desigItems[i]['frequencies'] = frequencies
}
console.log(viewModel.desigItems());
}
var preBind = function() {
loadData();
loadFrequencies();
}
preBind();
ko.applyBindings(viewModel, $('#designnation-list-container')[0]);
})(jQuery, ko);
然后与以下视图关联:
<h1>Hello World</h1>
<div id="designnation-list-container" data-bind="foreach: desigItems">
<div class="donor-js-wid-desig-opt donor-style-box donor-style-2col">
<h2 class="donor-js-desig-desc" data-bind="text: desc"> </h2>
<img class="donor-js-desig-logo donor-style-donation-image" alt="Web Desc 10000 - adding this" src="https://d36vh9gkg2fzwi.cloudfront.net/imageserver/be1b7b8e195587ff422c40750a6caa9f/10000_IPHONE_v1.JPG">
<form method="post" enctype="multipart/form-data" action="javascript:">
<input class="donor-js-wid-desig" type="hidden" name="gift_desig" value="10000">
<p class="donor-js-desig-shorttext" data-bind="html: shortdesc"> </p>
<p id="donor-js-donation-amount-label">
<label class="donor-style-label">Donation Amount</label>
</p>
<p>
<div data-bind="foreach: amount_options">
<label class="donor-js-amount-choice">
<input type="radio" class="donor-js-webware" name="gift_amt" data-bind="attr: {value: desc}, checked: selected"><span class="donor-js-currency-symbol">$</span> <span class="donor-js-amount" data-bind="text: desc"></span> <span class="donor-js-input-currency"></span><br>
</label>
</div>
<label>
<input type="radio" class="donor-js-other-amount-opt" name="gift_amt" value="other">
<span id="donor-js-other-label">Amount:</span>
<span class="donor-js-currency-symbol">$</span></label>
<input class="donor-js-other-amount-input" type="text" name="other_amt" onclick="$(this).closest('form').find('input[class=donor-js-other-amount-opt]').attr('checked', true);"> <span class="donor-js-input-currency"></span>
</p>
<p>
<select class="donor-js-wid-frequency" name="gift_freq" data-bind="options: frequencies, optionsText: desc, value: desc"></select>
</p>
<p id="donor-js-gift-notes" style="display:none">
<label class="donor-js-gift-note-label">Gift Notes
<textarea name="gift_note" class="donor-style-select" rows="2" cols="40"></textarea>
</label>
</p>
<p><input type="submit" class="donor-js-dona-submit button" value="Add to Cart"><input type="button" class="donor-js-desig-info donor-style-buttonlink" value="show more details">
</p></form>
<div class="donor-style-clearb"></div>
</div>
</div>
我知道有很多东西要接受,但我有一个特定的功能有问题:_processFrequenciesData
看到的问题是,我有一个选择元素:
<p>
<select class="donor-js-wid-frequency" name="gift_freq" data-bind="options: frequencies, optionsText: desc, value: desc"></select>
</p>
正如您可能从我发布的初始视图中看到的,这个select元素位于self.desigItems
上循环的循环中
此函数(_processFrequenciesData
)中有一个console.log
,但它返回:[]
你会认为,好吧,也许数据没有被提取,接受它在这一点上,因为7个项目被渲染到屏幕上。
我想做的是说,好吧:把这个frequencies
列表添加到每个desigItems
中
那么,为什么当我console.log(viewModel.desigItems)
时,我得到了一个空数组,而当视图遍历desigItems时,我又得到了七个东西呢?
observableArray
不是数组。它是包装数组的函数(!)(就像observable
不是值,而是包装值的函数一样)。要检索实际值,必须调用一个可观测值:
// Push frequencies on to each of the design items in the list.
var desigItems = viewModel.desigItems(); // access the underlying array
for (var i = 0; i < desigItems.length; i++) {
desigItems[i].frequency = frequencies[i];
}
viewModel.desigItems.notifySubscribers();
console.log(viewModel.desigItems());
您所做的是向可观察对象本身添加属性,但这不会影响可观察对象包含的值。
现在,由于我们已经改变了viewModel.desigItems
的基本值,而没有给敲除一个注意的机会,我们必须调用notifySubscribers()
来通知每个人可观察到的值已经改变。
话虽如此,我会这样重写你的整个代码:
(function($, ko){
function ViewModel() {
var self = this;
self.errorMessages = ko.observableArray();
self.desigItems = ko.observableArray();
self.frequencies = ko.observableArray();
}
var viewModel = new ViewModel();
$(function () {
ko.applyBindings(viewModel, $('#designnation-list-container')[0]);
});
var desigsReq = $.ddcApiGet('/widget/desigs.json').done(viewModel.desigItems);
var freqsReq = $.ddcApiGet('/widget/freqs.json').done(viewModel.frequencies);
$.when(desigsReq, freqsReq).done(function (desigs, freqs) {
desigs.forEach(function (desig, i) {
desig.frequency = freqs[i];
});
}).fail(viewModel.errorMessages);
})(jQuery, ko);
这修复了代码中的两个定时问题:
- 在文档准备就绪之前,不能绑定视图模型
- 您必须等待两个Ajax请求都完成,然后才能组合结果
以这种方式组合两个数组是否真的有用是另一回事。我认为这不是一个很干净的解决方案。
附言:你真的可以把这个问题缩短,实际上你发布的代码都与手头的问题无关。
那么,为什么当我
console.log(viewModel.desigItems())
时,我得到了一个空数组,而当视图遍历desigItems时,我又得到了七个东西呢?
_processFrequenciesData
回调函数中有console.log(viewModel.desigItems)
调用。
但是,您不会在那里填充viewModel.desigItems
,而是在_processLoadedData
回调函数中填充。
这可能是一个简单的错误。您可能只想将console.log(...)
移到另一个回调中。
按照现在的方式,当loadFrequencies
的响应在loadData
的响应之前处理时,您将有一个空的控制台输出(正如您所看到的)。
- jquery数据表的自定义ko绑定
- ko.com在foreach$data变量上添加了write函数
- 如何使双输入可写ko.computed
- 从对象内部调用knockout.js ko.applyBindings()
- 淘汰赛JS;绑定值未更新或 ko.computed() 未更新
- ko observablearray:推送和直接分配之间的区别
- KO 绑定复选框:从代码更改“选中”属性,不更改可观察字段
- 将 d3 演示中的圆圈和文本替换为包含自定义 HTML 和 ko 绑定的 foreignObject
- KNOCKOUT ko.observableArray 不会刷新视图
- 如何迭代ko.OberableArray
- 在ko.applyBindings(..)中执行Knockout js订阅函数(用于可观察对象)
- 防止拖动上的ko点击绑定
- 如何刷新'选项'ko多选组件中的绑定
- knockoutjs undo ko.mapping.fromJS
- KnockoutJS 通过 ko.utils.extend 继承功能
- 调用ko.applyBindings后,向Knockout视图模型添加新属性
- Knockout mapping用于ko.mapping.toJSON()的选项-方法
- 将 a ko.observable 更改为 ko.computed,反之亦然
- KO网格无法保存编辑单元格中的数据-使用Plunker
- Not understanding ko.obseravables