2016-05-15 49 views
3

input控件的value传递给视图模型函数的语法是什么(假设有一个)?在我的场景中,我不想将输入的值绑定到viewmodel上的属性。我只需要对输入控件中输入的值进行操作(基本上,我正在遍历项目集合并过滤掉那些不包含输入文本的项目)。将输入元素的值作为参数传递给视图模型函数

<input data-bind="text: filterText($data), valueUpdate: 'afterkeydown'"> 

我试过filterText($data, value)但淘汰赛试图寻找在视图模型value财产。我实际上需要输入控件的当前值。

这可能吗?

回答

4

处理此用例的典型方法是使用textInput与调用filterText的绑定值上的订阅进行绑定。

<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()

0

如果你没有将属性绑定到视图模型,那么你可以使用jquery/javascript直接在你的视图模型函数中获取输入控件的值。

self.Filter= function() {   
    var filter = $('#textBoxID').val(); 
    //  
} 

这样,您不需要将值传递给您的视图模型函数参数。

+0

为什么投票没有理由? – pso

+0

这不适用于OP的视图代码,它具有“文本”绑定。另外,假设有一个'value'绑定,这个解决方案在技术上是可行的,但它不是惯用的KnockoutJS,完全依赖于KO在内部工作的副作用,并且导致我的经验中出现问题。 – Jeroen

+0

但是这个人已经声明“在我的场景中,我不想将输入的值绑定到视图模型上的属性。”我的解决方案适用于他相信的场景。 – pso

1

第一件事是第一件事。您的示例代码在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 computeds你会发现,接受用户输入或没有,如果满足一定条件其实用例为了这。

选项3
我建议什么,虽然,如果我改一下你的要求一点:

你怎么到inputvalue变化与惯用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,但对于不同的事件?

1

使用$ element.value来访问输入的值。

相关问题