Knockout.js得到DOM对象的数据相关联(Knockout.js get dom objec

2019-06-23 14:06发布

我与knockout.js合作,建立动态列表,我试图找出如何我可以得到我的观察到的数组对象关联的DOM对象。 具体来说,我想要得到jQuery的一个排。

例:

<ul data-bind="foreach: Item">
    <li data-bind="events: {click: getDomObject}, text: 'text: ' + text">
    </li>
</ul>

getDomObject功能,我希望能够得到具体的<li></li> DOM对象,这样我可以做一些jQuery的操纵它。

我想过加入id成员的项目视图模型,然后添加id作为行项目的HTML ID,然后选择基于这一点,但我觉得应该有一个更简单的方法。

什么是引用由knockout.js产生的动态HTML的正确方法?

Answer 1:

像click事件处理程序获得通过两个参数。 那是

  1. 该事件属于项目 - 就像你曾经用的foreach渲染结合(在你的情况下,“项目”)可观察到的数组的入口。

  2. 而且,事件对象,它为您提供有关实际事件的详细信息。 这个对象包含得到点击(重点“目标”)的DOM元素:

     getDomObject = function(item, event) { var $this = $(event.target); // ... } 

只是注意:不要混合淘汰赛和本地jQuery的DOM操作 - 如果你能达到与巧妙的淘汰赛绑定相同的结果,我会建议与去。

这里是一个简单的演示: http://jsfiddle.net/KLK9Z/213/

 var Item = function(color) { this.color = String(color); this.setTextColor = function(item, event) { $(event.target).css('background', color); }; }; ko.applyBindings(new function() { this.Items = ko.observableArray([ new Item('red'), new Item('blue'), new Item('green') ]); }()); 
 li { padding: 2px 10px; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/2.0.0/knockout-min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <ul data-bind="foreach: Items"> <li> <button data-bind="click: setTextColor, text: 'Color: ' + color"></button> </li> </ul> 



Answer 2:

如果是涉及到一个已经发生的事件进行该产品的DOM元素为目标$(event.target)解决方案是好的。 但有时你没有针对性的项目,因为没有事件(例如 - 要滚动列表,以不是由用户手势的项目)。

在这种情况下,你可以给该项目的DOM元素ID属性包含该项目ID的唯一值:

<li data-bind="attr: {id: 'item_' + id}">

然后getDomObject()是这样的:

getDomObject = function(item) { return $("#item_" + item.id); }


Answer 3:

又增加一个第三选择,也是在那里你没有一个事件一起工作的情况下(如果你有一个事件,接受的答案是最好的/优化)。

创建自定义的绑定,这样:

ko.bindingHandlers.scrollTo = {
    update: function(element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        if (value) {
            var scrollParent = $(element).closest("div");
            var newTop = $(element).position().top + scrollParent.scrollTop();
            scrollParent.scrollTop(newTop);
        }
    }
};

用法如下:

<li data-bind="scrollTo: $parent.scrollTo() && $parent.scrollTo().id == id">

在上述情况下,$父是我的视图模型。 我有一个包含一个唯一的ID可观察到的对象。 每当我设置scrollTo()对象,列表滚动到该项目。

请注意,我的代码假设李父DIV有滚动条(溢出:自动/滚动)。 您可以调整您的需求,可能是使用一类的家长和使用您的jQuery选择,或者进行非常灵活,你可以在选择通过您的数据绑定选项传递......对我来说,这是不够的,因为我总是用div的我的滚动部分。



Answer 4:

我有一个类似的问题。 我想出了一个解决方案类似于Backbone.js的使用EL和$ EL引用。

在您的视图模型:

var myViewModel = function(){
  var self = this;

  //html element
  self.el = ko.observable();

  //jquery wrapped version
  self.$el = ko.observable();
}

在HTML(例如列表元素):

<!-- left side is the name of the handler, right side is name of the observable -->
<li class="myclass" data-bind="el: el, $el: $el"></li>

在bindingHandlers(示出所有可能的参数INIT):

ko.bindingHandlers.el = {
  init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
    var value = valueAccessor();
    //assign value to observable (we specified in html)
    value(element);
  }
};

ko.bindingHandlers.$el = {
  init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
    var value = valueAccessor();
    //here we first create a jQuery object by using $(myelem)
    //before updating observable value
    value($(element).first());
  }
};

例如,那么你可以使用$ EL这样的:

var myViewModel = function(){
  var self = this;

  //plain DOM element reference
  self.el = ko.observable();

  //jquery object reference
  self.$el = ko.observable();

  self.myFunction = function() {
    console.log(self.$el().html());
    self.$el().addClass("myCssClass");
  }
}

希望这可以帮助!



Answer 5:

我的解决方案(适用于“价值”的结合)

 ko.bindingHandlers.value.preprocess = function(val, name, cb) {
    /* every time I set a data-bind="value: xxxx" with an 
     * observable xxxx add also a data-bind="domElement: xxxx" */
    cb('domElement', val );
    return val;
}

ko.bindingHandlers.domElement = {
    /* For each data-bind="domElement: xxxx" add an extension "element" */
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
      valueAccessor().extend({element: element });
    }
  };

ko.extenders.element = function (target, element) {
    /* element extension add el and $el to observable xxxx */
    target.el = element;
    target.$el = $(element);
} 

现在你有yourobservable。$ E1和yourobservable.el结合到jQuery和DOM元素。



文章来源: Knockout.js get dom object associated with data