2015-07-28 124 views
0

我想访问一个jQuery对象,这恰好是一个输入文本框来做一些验证并添加日期选择器,但不幸的是我无法这样做。从自定义绑定处理程序中访问jQuery对象

我正在与KnockoutJS合作。

如果'Datatype'碰巧是'Date'或'Datetime',我想访问'input'并调用它的datepicker()。但每当我尝试使用.closest('td').next('td').html()进行搜索时,我都会得到一个null(来自自定义绑定内)。试一试,以便我可以根据数据类型'td'在输入上调用datetimepicker构造函数。

下面是我试图用

的jsfiddle工作小提琴:http://jsfiddle.net/sourabhtewari/nkkt88v2/2/

var format = function (str, col) { 
    col = typeof col === 'object' ? col : Array.prototype.slice.call(arguments, 1); 

    return str.replace(/\{\{|\}\}|\{(\w+)\}/g, function (m, n) { 
     if (m == "{{") { 
      return "{"; 
     } 
     if (m == "}}") { 
      return "}"; 
     } 
     return col[n]; 
    }); 
}; 

var data = ko.observableArray([{ 
    paramKey: ko.observable('keyName'), 
    paramValue: ko.observable('Test1'), 
    dataType: ko.observable('Date') 
}]); 


var ParamConstr = function (key, value, dataType) { 
    return { 
     ParamKey: ko.observable(key), 
     ParamValue: ko.observable(value), 
     DataType: ko.observable(dataType) 

    }; 
}; 
var my = my || {}; 
function Generator() { }; 

Generator.prototype.rand = Math.floor(Math.random() * 26) + Date.now(); 

Generator.prototype.getId = function() { 
    return this.rand++; 
}; 
var idGen = new Generator(); 
//var ParamData = ko.observableArray([]); 
my.viewModel = { 
    ParamData : ko.observableArray([]), 
    addParam: function() { 
     this.ParamData.push(new ParamConstr("$$" + "key1", "value1","Date")); 
    }}; 

ko.bindingHandlers.hidden = { 
    update: function (element, valueAccessor) { 
     ko.bindingHandlers.visible.update(element, function() { return !ko.utils.unwrapObservable(valueAccessor()); }); 
    } 
}; 


ko.bindingHandlers.clickToEdit = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, context) { 

     var observable = valueAccessor(), 
      link = document.createElement("a"), 
      input = document.createElement("input"); 

     var id = idGen.getId(); 
     input.setAttribute("id", id); 

     element.appendChild(link); 
     element.appendChild(input); 


     console.log(document.getElementById(id).id); 

     var dataType = $(format("#{0}", id)).parent().next('td').html(); 
     //.parent().next().html(); 
     //.closest('td').next('td').html().toString(); 
     console.log(dataType); 

     switch ($(format("#{0}", id)).parent().next('td').html()) { 

      case "Datetime": 
       $(format("#{0}", id)).datetimepicker(); 
       break; 

      case "Date": 
       $(format("#{0}", id)).datetimepicker({ 
        timepicker: false, 
        format: 'Y/m/d' 
       }); 
       break; 
     } 

     observable.editing = ko.observable(false); 

     ko.applyBindingsToNode(link, { 
      text: observable, 
      hidden: observable.editing, 
      click: observable.editing.bind(null, true) 
     }); 

     ko.applyBindingsToNode(input, { 
      value: observable, 
      visible: observable.editing, 
      hasfocus: observable.editing, 
      event: { 
       keyup: function (data, event) { 
        //if user hits enter, set editing to false, which makes field lose focus 
        if (event.keyCode === 13) { 
         input.blur(); 
         observable.editing(false); 
         return false; 
        } 
        //if user hits escape, push the current observable value back to the field, then set editing to false 
        else if (event.keyCode === 27) { 
         observable.valueHasMutated(); 
         observable.editing(false); 
         return false; 
        } 

       } 
      } 
     }); 
    } 
}; 

ko.applyBindings(my.viewModel); 

HTML:

<div> 
    <button id="InputSubmitBtn" type="submit" class="btn btn-custom" data-bind="click: addParam"><span class="glyphicon glyphicon-plus-sign"></span>&nbsp;Add</button> 
</div> 
<table class="table table-hover table-condensed"> 
    <thead> 
     <tr> 
      <th>Name</th> 
      <th>Value</th> 
      <th>Data type</th> 
     </tr> 
    </thead> 
    <tbody data-bind="foreach: ParamData"> 
     <tr> 
      <td data-bind="text: ParamKey" style="width: 20%"></td> 
      <td data-bind="clickToEdit: ParamValue" data-text="" style="width: 20%"></td> 
      <td data-bind="text: DataType" style="width: 20%"></td> 
     </tr> 
    </tbody> 
</table> 

任何帮助,我怎么能解决这个问题将是巨大的!

+1

如果你的目标是让数据类型,那么你可以使用allbindingaccessors参数来实现它。 修改您的HTML到 和在自定义结合 添加以下行给出你的数据类型为 var dataType = allBindingsAccessor()。datatype(); console.log(allBindingsAccessor()。datatype());.您可以将其用作切换大小写以与所需数据类型进行比较的输入。检查它,让我们知道它是否有效 –

+0

这样做的工作。谢谢。 – Navyseal

+0

很高兴听到它的工作。快乐的编码 –

回答

0

所以看来你从G_S得到了答案。

如果有人想知道什么是正确的选择,var dataType = $(element).next().text();完美的工作。你无法访问任何数据,因为在通话时,它还没有。您可以尝试var dataType = $(element).prev().text();并查看您可以检索$$ key1。

Fiddle

无论如何,你得到了回答,我没有进一步的挖掘就如何解决这个问题,有一个美好的一天:)