这是我正在使用的代码。控制台日志显示我正在调用onFilterChange方法两次(对于“select tags”中的每个函数定义一次。我猜我需要在data-bind中更改“event:{change:onFilterChange}”,但是我不熟悉Knockout.js,我们不支持ES6,所以不要使用“()=> onFilterChange”,这对我来说过去很有用:
function ProductionsView() {
var self = this;
self.showDateFilter = ko.observable(true);
self.showCategoryFilter = ko.observable(true);
self.showDateFilter = ko.observable(true);
self.onFilterChange = function(data,event) {
if (self.init()) {
self.doFilter();
console.log("onFilterChange was called. This is happening twice on page load before interacting with the filter. ");
}
};
self.doFilter = function() {
var df = self.selectedDateFilter();
var cf = self.selectedCatFilter();
if (typeof cf == 'undefined' || typeof df == 'undefined') {
return;
}
// these are all defined as observables too, but not important since it's the "onFilterChange" that I don't want to call
self.amFiltering("All" !== df || "All" !== cf);
self.allCatAndDate("All" === df && "All" === cf);
self.offset(0);
self.doAjaxSearchFiltered(true);
};
}
var pv = new ProductionsView();
ko.applyBindings(pv);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="visible: showDateFilterBar()">
<select data-bind="
value: selectedCatFilter,
event: { change: onFilterChange },
visible: showCategoryFilter()
">
<option value="all">all</option>
<option value="cat1">cat1</option>
</select>
<select data-bind="
value: selectedDateFilter,
event: { change: onFilterChange },
visible: showDateFilter()
">
<option value="all">all</option>
<option value="date1">date1</option>
</select>
</div>
答案 0 :(得分:0)
我猜测当你的初始值传递给select元素时,applyBindings本身会触发更改事件。
您应该在模型中订阅observables本身的change事件,而不是在标记中订阅事件绑定。
self.selectedCatFilter.subscribe(onFilterChange);
self.selectedDateFilter.subscribe(onFilterChange);
答案 1 :(得分:0)
是的,你使用Knockout错了。 Knockout是关于自动值依赖性的,通常你不需要设置任何&#34;更改&#34;事件处理程序。
您设置了observable并订阅了它们。您将在更改时收到通知,例如,当用户更改了绑定的UI元素时,或其依赖项之一发生更改时。
要订阅可观察的值,只需在computed
或.subscribe()
内直接使用它们即可。两者都显示如下。运行代码示例以查看它的实际效果。
function ProductionsView() {
var self = this;
// values
self.selectedDateFilter = ko.observable("all");
self.selectedCatFilter = ko.observable("all");
// computed values
self.amFiltering = ko.computed(function () {
return self.selectedDateFilter() !== "all" ||
self.selectedCatFilter() !== "all";
});
self.allCatAndDate = ko.computed(function () {
return self.selectedDateFilter() === "all" &&
self.selectedCatFilter() === "all";
});
// subscriptions
self.amFiltering.subscribe(function (value) {
console.log("searching with filter=" + value);
//self.doAjaxSearchFiltered(value);
});
}
var pv = new ProductionsView();
ko.applyBindings(pv);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select data-bind="value: selectedCatFilter">
<option value="all">all</option>
<option value="cat1">cat1</option>
</select>
<select data-bind="value: selectedDateFilter">
<option value="all">all</option>
<option value="date1">date1</option>
</select>
Viewmodel:
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>
&#13;
您可以创建一个包含Ajax参数的计算值作为对象并订阅它,如下所示:
self.searchParams = ko.computed(function () {
return {
date: self.selectedDateFilter(),
cat: self.selectedCatFilter()
};
});
self.searchParams.subscribe(function (params) {
return $.get("/your/url", params).done(function (data) {
// populate your observables with new data
});
});
这样就可以在任何相关更改时自动触发Ajax请求。