Data binding 在页面加载时未初始化扩展程序中已初始化/附加到可观察对象的可观察对象

Data binding 在页面加载时未初始化扩展程序中已初始化/附加到可观察对象的可观察对象,data-binding,knockout.js,extender,bindinghandlers,Data Binding,Knockout.js,Extender,Bindinghandlers,我 我创建了一个文本计数器,告诉用户他们已经输入了多少个字符,还有多少个字符可以使用。当文本区域具有焦点并消失,然后文本区域失去焦点时,应显示此信息 我创建了一个绑定处理程序,它使用扩展程序来扩展传递给它的可观察对象。问题是,它只有在输入文本、导航离开文本区域,然后导航回文本区域后才能工作 <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> </head>

我 我创建了一个文本计数器,告诉用户他们已经输入了多少个字符,还有多少个字符可以使用。当文本区域具有焦点并消失,然后文本区域失去焦点时,应显示此信息

我创建了一个绑定处理程序,它使用扩展程序来扩展传递给它的可观察对象。问题是,它只有在输入文本、导航离开文本区域,然后导航回文本区域后才能工作

<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>
页面从一开始就将按照我希望的方式运行,但它违背了使用扩展程序的全部目的,因为我的视图模型现在有一个来自扩展程序的对象

我必须相信,我在这里遗漏了一些相对简单的东西


感谢您的帮助。

问题是解析此处的绑定字符串时,
hasFocus
尚未定义:

<textarea data-bind="textCounter: successes, hasFocus: successes.hasFocus, maxLength:200, event: { keyup:successes.updateRemaining }"></textarea>

因此,当解析绑定字符串时,
successfulls.hasFocus
是未定义的

一个选项是在
hasFocus
属性可用后,在
textCounter
绑定中应用
hasFocus
绑定


此外,在Knockout 3.0(今天发布)中,当在绑定本身中访问该值时,就会对绑定字符串进行解析。因此,您的代码实际上已经在KO 3.0中运行了。

我继续并升级到了KO 3.0
<textarea data-bind="textCounter: successes, hasFocus: successes.hasFocus, maxLength:200, event: { keyup:successes.updateRemaining }"></textarea>