如何在 Knockout JS 中创建实用方法?

How to create a utility method in knockout JS?

<input type="text" id="txtFirstname" data-bind="value:firstName,valueUpdate:'afterkeydown'" />
<i data-bind="css:RequiredStyle(firstName)"></i>
  var ViewModel = function () {
    var self = this;

    self.firstName = ko.observable("Hello World!");

    self.RequiredFieldStyle=function (controlValue) {
        alert('called');
        var hasValue = controlValue().length;
        if (hasValue > 0) {
            return "fa fa-check-circle";
        } else {
            return "fa fa-exclamation-circle";
        }
    };
};

如何为 knockout.js 中的 RequiredFieldStyle 函数创建实用方法?

您应该订阅您的 input observable 并定义另一个 observable 变量来设置您图标的 CSS,然后每当输入发生变化时,CSS 变量就会自动设置。
示例:http://jsfiddle.net/GSvnh/5102/

var MainViewModel = function () {
        var self = this;
        self.firstName = ko.observable("Hello World!");
        self.CSS = ko.observable(); 
        self.firstName.subscribe(function(controlValue){

         var hasValue = controlValue.length;
            if (hasValue > 0) {
                self.CSS("fa fa-check-circle");
            } else {
                self.CSS("fa fa-exclamation-circle");
            }
        })

  }

查看:

<input type="text" id="txtFirstname" data-bind="value:firstName,valueUpdate:'afterkeydown'" />
<i data-bind="css:CSS"></i>

让我提供一个替代方案。尽管使用手动订阅可能很有用,但恕我直言,在 Knockout 中有更优雅的方法可以做到这一点。最基本的是计算可观察值:

var MainViewModel = function() {
  var self = this;
  self.firstName = ko.observable('');
  self.validnessCssClass = ko.computed(function() {
    return !self.firstName() ? 'fa-exclamation-circle' : 'fa-check-circle';
  });
}

ko.applyBindings(new MainViewModel());
.fa { color: red; font-weight: bold; }
.fa-check-circle:before { content: " "; }
.fa-exclamation-circle:before { content: "!!!"; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>

<input type="text" data-bind="value: firstName, valueUpdate: 'afterkeydown'" />
<i class="fa" data-bind="css: validnessCssClass"></i>

第二种方法使用 extenders that will make the resulting code look a lot like that from knockout-validation。哎呀,链接文档甚至包含一个 required 验证的示例,让我 post 在这里逐字逐句:

ko.extenders.required = function(target, overrideMessage) {
    //add some sub-observables to our observable
    target.hasError = ko.observable();
    target.validationMessage = ko.observable();

    //define a function to do validation
    function validate(newValue) {
       target.hasError(newValue ? false : true);
       target.validationMessage(newValue ? "" : overrideMessage || "This field is required");
    }

    //initial validation
    validate(target());

    //validate whenever the value changes
    target.subscribe(validate);

    //return the original observable
    return target;
};

如果您需要它可以重复使用,您可以使用 custom binding

在你的情况下,这样的事情可能有效

ko.bindingHandlers.checkIcon = {
            init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
                $(element).removeClass('fa-check-circle fa-exclamation-circle');
                var v = ko.utils.unwrapObservable(valueAccessor());
                $(element).addClass(v.length ? 'fa-check-circle' : 'fa-exclamation-circle');
            },
            update: function(element, valueAccessor, allBindings, context, bindingContext) {
                $(element).removeClass('fa-check-circle fa-exclamation-circle');
                var v = ko.utils.unwrapObservable(valueAccessor());
                $(element).addClass(v.length ? 'fa-check-circle' : 'fa-exclamation-circle');
            }
        }
        
 var vm = {
   firstName:ko.observable('')
 }
 
 ko.applyBindings(vm);
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.css" rel="stylesheet"/>
<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.2.0/knockout-min.js"></script>

<input type="text" data-bind="textInput:firstName"/>

<span class="fa" data-bind="checkIcon:firstName"></span>