第一件事是第一件事。您的示例代码在input
节点上使用a text
binding,这并不是那么有用(这意味着从视图模型到DOM的单向单向绑定,该input
的“文本”内容是无意义的)。鉴于目前的valueUpdate
绑定你可能意味着the value
binding?请注意,the textInput
binding是在现代版本的KnockoutJS中结合这两者的方式。
至于你的实际问题,重要的背景缺失:为什么你(想你)想要做到这一点?根据具体情况,解决方案会有所不同,或者甚至可能会有XY-problem。
无论如何,要答案。
选项1
尝试仍然回答具体问题,我第二@JohnnyHK's answer您观察到的是一个可能的解决方案编写.subscribe
的。
选项2
另一种可能的解决方案十分相似的那一个,而是试图满足“我不感兴趣输入的值”的一部分,我建议使用只读计算观察到:
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
功能。 我不建议这个,而是建议使用一个私有变量,支持可观察的读取和写入。实际上,这会使该选项等同于其他答案中的第一个选项。
一个有趣的注意,虽然,你的问题的关于“聚集”和过滤输入比特:如果你看一下the docs from writeable computed
s你会发现,接受用户输入或没有,如果满足一定条件其实用例为了这。
选项3
我建议什么,虽然,如果我改一下你的要求一点:
你怎么到input
value
变化与惯用KnockoutJS反应过来的时候你的行动不会关心实际的value
?
要编写与DOM的自定义交互,有custom binding handlers。你可以有一个根本不使用ViewModel,或者有一个可观察的。
选项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,你确实需要新的价值,因此不应该看afterkeydown
,但对于不同的事件?
为什么投票没有理由? – pso
这不适用于OP的视图代码,它具有“文本”绑定。另外,假设有一个'value'绑定,这个解决方案在技术上是可行的,但它不是惯用的KnockoutJS,完全依赖于KO在内部工作的副作用,并且导致我的经验中出现问题。 – Jeroen
但是这个人已经声明“在我的场景中,我不想将输入的值绑定到视图模型上的属性。”我的解决方案适用于他相信的场景。 – pso