Knockout JS “uniqueName” binding - Same name to two fields

前端 未结 4 1032
遇见更好的自我
遇见更好的自我 2021-01-14 09:31

I am using Knockout JS to create an editor. I am using the foreach property to loop around a list in my model.

 

        
相关标签:
4条回答
  • 2021-01-14 09:42

    I wanted to post as a comment, but my reputation is too low... Thank you very much RP Niemeyer for your post.

    I don't know if this has something to do with requirejs and knockout modules, but I had to change

    ko.bindingHandlers.uniqueName.currentIndex 
    

    to

    ko.bindingHandlers.uniqueName.Zb
    

    so now I have:

    define(["knockout"], function(ko) {
        ko.bindingHandlers.valmsg = {
            init: function (element) {
                element.setAttribute("data-valmsg-for", "ko_unique_" + ko.bindingHandlers.uniqueName.Zb);
            }
        };
    });
    
    0 讨论(0)
  • 2021-01-14 09:52

    You only need to add a ControlName attribute in the child elements and bind the input name to this and the data-valms-for too

    <input type="number" class="form-control" data-bind="value: myValue, valueUpdate: 'afterkeydown', attr: {ControlName}" required /> 
    <span class="field-validation-valid" data-bind='attr: {"data-valmsg-for":ControlName}' data-valmsg-replace="true"></span>
    
    0 讨论(0)
  • 2021-01-14 09:54

    A possibly simpler approach derived from RP-Niemeyer's excellent solution:

    <span class="field-validation-valid" data-bind='attr: {"data-valmsg-for": "ko_unique_" + ko.bindingHandlers.uniqueName.currentIndex}' data-valmsg-replace="true" />
    
    0 讨论(0)
  • 2021-01-14 10:08

    The uniqueName binding just increments an index and sets the name (with a fix for IE).

    It looks like:

    ko.bindingHandlers['uniqueName'] = {
        'init': function (element, valueAccessor) {
            if (valueAccessor()) {
                element.name = "ko_unique_" + (++ko.bindingHandlers['uniqueName'].currentIndex);
    
                // Workaround IE 6/7 issue
                // - https://github.com/SteveSanderson/knockout/issues/197
                // - http://www.matts411.com/post/setting_the_name_attribute_in_ie_dom/
                if (ko.utils.isIe6 || ko.utils.isIe7)
                    element.mergeAttributes(document.createElement("<input name='" + element.name + "'/>"), false);
            }
        }
    };
    

    So, you can create a custom binding that uses the last index and sets the appropriate attribute

    ko.bindingHandlers.valmsg = {
        init: function(element) {
            element.setAttribute("data-valmsg-for", "ko_unique_" + ko.bindingHandlers.uniqueName.currentIndex);
        }
    };
    

    Now, you would just use it like:

    <tr>
        <td>
             <input data-bind='value: type, uniqueName: true' data-val="true", data-val-required="The Type field is required"  />
        </td>
    </tr>
    <tr>
         <td class="field-validation-valid" data-bind="valmsg: true" data-valmsg-replace="true"></td>
    </tr>
    
    0 讨论(0)
提交回复
热议问题