将input
控件value
传递给viewmodel函数的语法是什么(假设有一个)?在我的场景中,我对将输入的值绑定到viewmodel上的属性不感兴趣。我只需要对输入控件中输入的值进行操作(基本上我会迭代一组项目并过滤掉那些不包含输入文本的项目。)
<input data-bind="text: filterText($data), valueUpdate: 'afterkeydown'">
我已尝试filterText($data, value)
但Knockout正试图在viewmodel上找到value
属性。我实际上需要来自输入控件的当前值。
这可能吗?
答案 0 :(得分:4)
处理此用例的典型方法是对调用filterText
的绑定值使用textInput
绑定和订阅。
<input data-bind="textInput: filter">
在你的剧本中:
filter.subscribe(function(newValue) {
filterText(newValue)
});
你可以简化为:
filter.subscribe(filterText);
但是你仍然可能在考虑这个错误。您的筛选列表应该是一个计算引用textInput绑定filter
值以计算筛选列表。
filteredList = ko.pureComputed(function() {
// return the list filtered by the bound filter() value
}, self);
然后,您可以在需要过滤的数据列表的任何地方使用filteredList()
。
答案 1 :(得分:1)
首先要做的事情。您的示例代码在input
节点上使用a text
binding,这不是那么有用(它意味着从视图模型到DOM的单向绑定,“文本“那个没有意义的input
的内容。鉴于valueUpdate
绑定存在,您可能意味着the value
binding?请注意the textInput
binding是在现代版本的KnockoutJS中将这两者结合起来的方式。
至于你的实际问题,缺少重要的背景:为什么你(想你)想要这样做?根据具体情况,解决方案会有所不同,或者您甚至可能会得到XY-problem。
无论如何,要回答。
选项1
尽管如此,我试图回答具体问题,我在你的观察点上写.subscribe
作为一种可能的解决方案的第二@JohnnyHK's answer。
选项2
另一个可能的解决方案非常类似于那个,但试图满足“我对输入的值”部分不感兴趣,我建议使用只读计算的observable:
function Root() {
var self = this;
self.filter = ko.computed({
read: function() { return ""; }, // <-- not recommended, read context!
write: function(newValue) {
// You're free to discard the newValue <-- not recommended, read context!
alert("Input has been changed.");
}
});
}
ko.applyBindings(new Root());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<input data-bind="textInput: filter">
现在这显然丢弃了写位中的newValue
(根据您的请求),因此也有一个奇怪的read
函数。 我不建议使用,而是建议使用带有后备observable的私有变量进行读写。但实际上,这将使该选项等同于另一个答案中的第一个选项。
一个有趣的说明,你的问题是关于“收集”和过滤输入:如果你看the docs from writeable computed
s你会发现接受用户输入或不满足某个条件是< / em>实际上是一个用例。
选项3
我建议使用,如果我稍微改写一下你的请求:
当您的操作不关心实际的
input
时,您如何对惯用的KnockoutJS进行value
value
更改做出反应?
为了编写与DOM的自定义交互,有custom binding handlers。你可以有一个根本不使用ViewModel的,或者有一个可观察的。(/ p>
选项3.A
ko.bindingHandlers["opacitor"] = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
$(element).on("keydown", function() {
$(this).animate({ opacity: 0.05 }, 1000, function() { $(this).animate({ opacity: 1.0 }, 1000); });
});
}
}
ko.applyBindings({});
input { background-color: gold; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<input data-bind="opacitor">
选项3.B
或者使用视图模型的第二个选项:
ko.bindingHandlers["opacitor"] = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
$(element).on("keydown", function() {
var speed = ko.utils.unwrapObservable(valueAccessor)();
$(this).animate({ opacity: 0.05 }, speed, function() { $(this).animate({ opacity: 1.0 }, speed); });
});
}
}
// speed1 and speed2 could also be observables
ko.applyBindings({ speed1: 500, speed2: 2000 });
input { background-color: gold; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<input data-bind="opacitor: speed1">
<input data-bind="opacitor: speed2">
选项3A和3B的缺点是您需要编写自定义事件处理逻辑。如果你看一眼the textInput
source from KO,你会发现它是非常简单来正确地跨浏览器处理这些事情。所以使用选项1或2可能仍然会更好(即使你有一些视图模型交互,即使“你不感兴趣”)。
选项4
使用the event
binding。这与选项3具有相同的缺点,但仍然可能是一个简单的解决方案。这是一个例子:
function Root(){
var self = this;
self.myFn = function(data, element) {
console.log(element.target.value);
return true;
};
}
ko.applyBindings(new Root());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<input data-bind="event: { keyup: myFn }">
您将在最后一个中看到一个微妙的变化,以及我想要结束的一个问题:您实际上没有this issue,您实际上需要 new 值因此不应该看afterkeydown
而是看一个不同的事件?
答案 2 :(得分:1)
使用$ element.value访问输入值。
答案 3 :(得分:0)
如果您没有将属性绑定到视图模型,那么您可以使用jquery / javascript直接在视图模型函数中获取该输入控件的值,方法是这样做。
self.Filter= function () {
var filter = $('#textBoxID').val();
//
}
这样您就不需要将值传递给view-model函数参数。