【问题标题】:applying bindings to dynamically generated html将绑定应用于动态生成的 html
【发布时间】:2020-06-11 19:21:02
【问题描述】:

我正在创建一个应用程序来管理一些列表项。该应用程序有一个包含可用列表项的菜单,用户可以选择一些要添加的列表项。选中的List项显示在一张表上,关键是每个ListItem都有一个Category,而且每个ListItem都必须显示在同一个category下。

这是添加新ListItem的方法:

self.addListItem = function () {
                let $itemsTable = $('#itemsTable');


                if (self.wineList.listItemModelsByCat.hasOwnProperty(this.category.title())) {
                    // the category is added already, just add the list item

                    self.wineList.listItemModelsByCat[this.category.title()].listItems.push({
                        item: this,
                        columnPrices : self.getColumnPricesModel()
                    })
                } else {


                    self.wineList.listItemModelsByCat[this.category.title()] = {
                        catTitle: ko.observable(this.category.title()),
                        listItems: ko.observableArray([{
                            item: this,
                            columnPrices: self.getColumnPricesModel()
                        }])
                    };

                    self.wineList.listItems.push(this);
                    self.listItems.remove(this);



                    // must create new model for this category
                    // and manage the ui

                    // add the category

                    let categoryMarkup  = '<tr>' +
                        `<td class="text-center list-category"
                                colspan="2" id="category_${this.category.id()}"> ${this.category.title()} </td>` +
                        '</tr>';

                    $itemsTable.find('tbody')
                        .append(categoryMarkup);



                    // add category items

                    let itemMarkup = '<tr class="spacer"> </tr>';

                    itemMarkup += `<tr>
                                    <td data-bind="text: wineList.listItemModelsByCat['${this.category.title()}']
                                            .listItems()
                                            .last()
                                            .item
                                            .title">
                                    </td>
                                  <td>
                                        <ul class="inline-list" data-bind="foreach: wineList.listItemModelsByCat['${this.category.title()}']
                                            .listItems()
                                            .last()
                                            .columnPrices">
                                            <li style="float: right" class="inline-list-item" >
                                                <input type="text" data-bind="textInput: price">
                                            </li>
                                        </ul>
                                  </td>
                                </tr>`;

                    $itemsTable.find('tbody')
                        .append(itemMarkup);


                     ko.applyBindings(self, $itemsTable.find('tbody > tr:last-child')[0])
                //
                }
            };


self.getColumnPricesModel = function() {
                let columnModel = ko.observableArray([]);

                self.wineList.columns().forEach((column) => {
                    let model = { title : ko.observable(column.title()),
                        price : ko.observable('')};

                        columnModel.push(model)
                });

                return columnModel;
            };

            self.updateColumnPricesModel = function() {
                Object.keys(self.wineList.listItemModelsByCat).forEach((key) => {
                    let item = self.wineList.listItemModelsByCat[key];
                    for (let i =0; i < item.listItems().length; i++) {
                        let listItem = item.listItems()[i];
                        listItem.columnPrices = self.getColumnPricesModel()
                    }
                })
            };

问题是数据绑定不适用于新添加的项目。我错过了什么吗?

【问题讨论】:

  • 我会准备一个jsFiddle,让问题更清楚。
  • fiddle 或 sn-p 肯定会有所帮助
  • @JasonSpake 这是一个小提琴jsfiddle.net/k8dz1um7
  • 如果你有你的物品清单并且你正在使用淘汰赛,你不需要在字符串中定义 html 元素。您可以在 html 文件中的敲除 foreach 绑定中编写您的结构,如果要添加数据,它将显示具有有效绑定的元素。对不起,如果我误解了你的问题。

标签: jquery data-binding knockout.js


【解决方案1】:

看来问题很简单,在我的updateColumnPricesModel

self.updateColumnPricesModel = function() {
                Object.keys(self.wineList.listItemModelsByCat).forEach((key) => {
                    let item = self.wineList.listItemModelsByCat[key];
                    for (let i =0; i < item.listItems().length; i++) {
                        let listItem = item.listItems()[i];
                        listItem.columnPrices = self.getColumnPricesModel()
                    }
                })
            };

self.getColumnPricesModel = function(isNew = true) {
    let columnModel = isNew ? ko.observableArray([]) : [];

    self.theList.selectedColumns().forEach((column) => {
      let model = {
        title: ko.observable(column.title()),
        price: ko.observable('')
      };

      columnModel.push(model)
    });

    return columnModel;
  };

在每次更新中,我都将 columnPrices 设置为新的 observableArray

listItem.columnPrices = self.getColumnPricesModel()我把这个改成

listItem.columnPrices(self.getColumnPricesModel(false))

它成功了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-21
    • 2014-10-19
    • 2017-01-30
    • 1970-01-01
    • 1970-01-01
    • 2015-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多