我 我创建了一个文本计数器来告诉用户他们输入了多少个字符以及剩余可用的字符数。这应该显示文本区域何时具有焦点并消失,然后文本区域失去焦点。
我创建了一个绑定处理程序,它使用扩展程序来扩展传递给它的可观察对象。问题是它只在输入文本,导航离开文本区域,然后导航回文本区域后才起作用。
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<div class="question" >
<label for="successes" data-textkey="successes">This is a question</label>
<textarea data-bind="textCounter: successes, hasFocus: successes.hasFocus, maxLength:200, event: { keyup:successes.updateRemaining }"></textarea>
<div class="lengthmessage edit" data-bind="visible:successes.hasFocus()">
<div >
<em>Length:</em> <span data-bind="text:successes.currentLength"></span>
<em>Remaining:</em> <span data-bind="text:successes.remainingLength"></span>
</div>
</div>
</div>
<script src="../Scripts/knockout-2.3.0.debug.js" type="text/javascript"></script>
<script type="text/javascript">
(function (ko) {
ko.extenders.textCounter = function (target, options) {
options = options || {};
options.maxLength = options.maxLength ? parseInt(options.maxLength) : 2000;
target.maxLength = ko.observable(options.maxLength);
target.currentLength = ko.observable(target().length);
target.remainingLength = ko.observable(target.maxLength() - target.currentLength());
target.hasFocus = ko.observable(false);
target.hasFocus.subscribe(function () {
target.currentLength(target().length);
target.remainingLength(target.maxLength() - target.currentLength());
});
target.updateRemaining = function (data, event) {
if (event.target == undefined && event.srcElement.value == "") {
target.currentLength(0);
}
else {
var e = $(event.target || event.srcElement);
target.currentLength(e.val().length);
if (target.currentLength() > target.maxLength()) {
e.val(e.val().substr(0, target.maxLength()));
target.currentLength(target.maxLength());
}
}
target.remainingLength(target.maxLength() - target.currentLength());
};
return target;
};
ko.bindingHandlers.textCounter = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var val = ko.utils.unwrapObservable(valueAccessor());
var observable = valueAccessor();
observable.extend({ textCounter: allBindingsAccessor() });
ko.applyBindingsToNode(element, {
value: valueAccessor()
});
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var val = ko.utils.unwrapObservable(valueAccessor());
var observable = valueAccessor();
ko.bindingHandlers.css.update(element, function () { return { hasFocus: observable.hasFocus }; });
}
};
var viewModel = function () {
this.successes = ko.observable("");
//this.successes.hasFocus = ko.observable();
}
ko.applyBindings(new viewModel());
} (ko));
</script>
</body>
</html>
如果我取消注释:
//this.successes.hasFocus = ko.observable();
从一开始,页面就会按照我想要的方式运行,但它会破坏使用扩展程序的整个目的,因为我的视图模型现在有一个来自扩展程序的对象。
我必须相信这里有一些相对简单的东西。
感谢您的帮助..
答案 0 :(得分:0)
问题是,在解析此处的绑定字符串时,尚未定义hasFocus
:
<textarea data-bind="textCounter: successes, hasFocus: successes.hasFocus, maxLength:200, event: { keyup:successes.updateRemaining }"></textarea>
因此,解析绑定字符串时successes.hasFocus
未定义。
一种选择是在hasFocus
属性可用后,在textCounter
绑定中应用hasFocus
绑定。
此外,在Knockout 3.0(今天发布)中,绑定字符串的解析发生在绑定本身中访问值时。因此,您的代码实际上已经在KO 3.0中运行了属性。