【问题标题】:Retrieve dynamically added element检索动态添加的元素
【发布时间】:2014-08-04 14:44:30
【问题描述】:

示例取自knockout tutorials - working with lists and collections

<table>
  <thead>
    <tr>
        <th>Passenger name</th>
        <th>Meal</th>
        <th>Surcharge</th>
        <th></th>
    </tr>
  </thead>
  <!-- Todo: Generate table body -->
  <tbody data-bind="foreach: seats">
    <tr>
        <td>
            <input data-bind="value: name" />
        </td>
        <td>
            <select data-bind="options: $root.availableMeals, value: meal, optionsText: 'mealName'"></select>
        </td>
        <td data-bind="text: formattedPrice"></td>
        </td>
    </tr>
  </tbody>
</table>

<button data-bind="click: addSeat">Reserve another seat</button>

ReservationsViewModel() 将一行元素动态添加到静态table on button(保留另一个座位)单击绑定到addSeatclick 事件侦听器。

function ReservationsViewModel() {
   var self = this;
   ...        
   self.addSeat = function () {
       self.seats.push(new SeatReservation("", self.availableMeals[0]));
   }
   ...
}

致电SeatReservation()

function SeatReservation(name, initialMeal) {
    var self = this;
    self.name = name;
    self.meal = ko.observable(initialMeal);
}

如何从SeatReservation()中的DOM(不是点击的元素)中检索添加的元素

编辑:据我了解淘汰赛的foreach 绑定,它重复子元素。我想要实现的是,一旦将这些元素添加到 DOM 中,就可以访问它们。

fiddle

【问题讨论】:

  • hmm...new SeatReservation (...).meal 是否包含您要查找的元素?如果你有参考的话,去 dom 是没有意义的
  • 我不认为 downvoter 是地球上最快的阅读器。
  • @KevinB 它绑定到foreach 循环。它遍历一个数组,然后添加元素。编辑:我是新来的淘汰赛,我不知道谁来检索添加的元素。我不想要整个元素,我想要点击“预订另一个座位”时添加的元素。
  • 您不应该真正访问 DOM。你为什么要这么做?
  • 如果你需要增强它,首选的方法是创建一个custom binding handler,它可以让你访问DOM元素

标签: jquery-mobile knockout.js


【解决方案1】:

您可以在foreach 绑定中使用afterRender 等后处理属性。

请参阅http://knockoutjs.com/documentation/foreach-binding.html 上的注释 7

afterRender 回调需要在您的主视图模型上定义,但由于它是作为参数传递当前数据项,您可以使用它来调用 SeatReservation 上的函数并传递 DOM 元素.

<tbody data-bind="foreach: { data: seats, afterRender: afterSeatRender }">

function SeatReservation(name, initialMeal) {
    // ...
    self.afterRender = function (elements) {
        $(elements).css('background-color', 'green');
    };
}

function ReservationsViewModel() {
    // ...
    self.afterSeatRender = function (elements, seat) {
        seat.afterRender(elements);
    };
}

这是一个更新的小提琴:http://jsfiddle.net/4J3Pf/2/

话虽如此,Knockout 的全部意义在于使用数据绑定而不是直接操作 DOM。 Knockout 文档清楚地表明这不是一个正常的用例:

这些回调仅用于触发与列表更改相关的动画。

特别是,在 SeatReservation 视图模型中操作 DOM 是错误的设计。尽量让你的视图模型和你的视图渲染代码分开。

【讨论】:

  • 感谢您的提琴。如果我在self.afterSeatRenderconsole.log(elements),它返回[text, tr, text]。我想检索 nodes / DOM 元素,这可能吗? jsfiddle.net/Palestinian/y6XnP
  • 我不明白你的意思。那些 被插入的三个原生 DOM 元素。我展示了如何在它们上设置 CSS background-color 属性作为示例。
【解决方案2】:

有了这个binding handler

ko.bindingHandlers.selectmenu = {
    init: function (element, valueAccessor, allBindings, viewModel, context) {
        $(element).parent().trigger("create");
        //you can customize the code depending on valueAccessor and allBindings
        //here
    }    
}

这样使用:

<select data-bind="selectmenu: {option1: optFromModel1, option2: optFromModel2}, 
                   options: $root.availableMeals, 
                   value: meal, 
                   optionsText: 'mealName'"></select>

它是works(你可以用ready替换pagebeforecreate

选择菜单更新来源:https://forum.jquery.com/topic/no-style-to-dynamic-select-element

【讨论】:

  • 谢谢,但是,请注意 ready() 不应在 jQM 中使用,.trigger("create") 已被弃用。我会测试你的方法。
  • 好的,一旦你有了 Dom 元素,你想使用什么方法?如果你有更好的方法我会更新
  • 我不想为每个元素使用单独的绑定,相反,我想检索添加的那些元素。每种元素类型都有不同的增强方法,这就是原因。我可以简单地在父元素上使用.enhanceWithin(),但我希望能够在注入后访问这些元素。
  • 我编辑了我的答案。如果您需要为每个元素进行自定义,您可以在绑定中包含参数。
  • 再次感谢。您误解了我,我想针对每个元素,例如selectinputbutton 等。所以我假设绑定应该附加到父容器(带有 foreach 绑定的元素)。请多多包涵,我今天才开始读 KO :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-30
  • 2017-02-09
  • 2022-01-19
  • 2013-05-27
  • 1970-01-01
  • 2021-06-15
  • 2014-09-03
相关资源
最近更新 更多