动态 adding/rendering Bootstrap select

Dynamically adding/rendering Bootstrap select

我正在使用 Knockout to create a dynamic form. I have a table and the user can add new rows to the table via a button click. My Bootstrap selectpicker 出现在第一行,但不在通过单击按钮添加的新行中。这是屏幕截图:

我的研究表明,当动态添加 Bootstrap select 时(如本例所示),每次都需要渲染。可以这样渲染:

$('.selectpicker').selectpicker('render');

这似乎是因为我在我的代码中的几个地方尝试了渲染。然而,尽管进行了几个小时的修补,我还是无法让它在每次单击按钮时都正确呈现。例如,有时它会在每一行呈现两个或多个 select 选择器。这是我的完整 Razor 页面代码:

@model Birder2.ViewModels.CreateObservationViewModel
@using Microsoft.AspNetCore.Identity
@inject UserManager<ApplicationUser> UserManager
@using Newtonsoft.Json
@{
    string data = JsonConvert.SerializeObject(Model);
}
@section scripts{
    <script src="~/js/knockout-3.4.2.js"></script>
    <script src="~/js/knockout.mapping-latest.js"></script>
    <script src="~/js/createobservationviewmodel.js"></script>
    <script type="text/javascript">
        var createObservationViewModel = new CreateObservationViewModel(@Html.Raw(data));
        createObservationViewModel.Observation.LocationLatitude = @UserManager.GetUserAsync(User).Result.DefaultLocationLatitude
            createObservationViewModel.Observation.LocationLongitude = @UserManager.GetUserAsync(User).Result.DefaultLocationLongitude
            ko.applyBindings(createObservationViewModel);
            $(select).selectpicker('render');
    </script>
}
<h2>Create an observation</h2>
<form>
    <div class="form-group">
        @* change to Partial View like Manage Index *@
        <span class="control-label" name="MessageToClient" data-bind="text: MessageToClient" />
    </div>

    <div class="form-group">
        <label class="col-sm-2 control-label" for="Observation.ObservationId">Id:</label>
        <div class="col-sm-10">
            <span class="form-control" name="Obervation.ObservationId" data-bind="text: Observation.ObservationId@*, event: {change: flagSalesOrderAsEdited}*@" />
        </div>
    </div>

    <div class="form-group">
        <label class="col-sm-2 control-label" for="Observation.ObservationId">Date:</label>
        <div class="col-sm-10">
            <input class="form-control" data-bind="datePicker : Observation.ObservationDateTime" type="date" />
        </div>
    </div>
    <div class="form-group">
        <input class="form-control" name="Observation.LocationLatitude" data-bind="value: Observation.LocationLatitude" />
        <input class="form-control" name="Observation.LocationLongitude" data-bind="value: Observation.LocationLongitude" />
    </div>
    <div class="form-group" spellcheck="true">
        <label class="col-sm-2 control-label" for="Observation.Note">Note:</label>
        <div class="col-sm-10">
            <input class="form-control" name="Observation.Note" data-bind="value: Observation.Note" />
        </div>
    </div>

    <hr />
    <hr />

    <table class="table table-striped">
        <tr>
            <th class="text-right">Quantity</th>
            <th class="text-right">Bird</th>
            <th><button class="btn btn-info btn-xs" data-bind="click: addObservedSpecies">Add</button></th>
        </tr>
        <tbody data-bind="foreach: ObservedSpecies">
            <tr>
                <td class="form-group"><input name="ObservedSpecies.Quantity" class="form-control input-sm text-right" data-bind="@*attr: {'id': 'Quantity_' + $index()},*@ value: Quantity@*, event: {change: flagSalesOrderItemAsEdited}*@" /></td>
                <td class="form-group">
                    @Html.DropDownListFor(m => m.Observation.BirdId,
                        new SelectList(Model.Birds, "BirdId", "EnglishName"),
                        new
                        {
                        @class = "form-control selectpicker show-tick",
                        data_bind = "value: BirdId",
                        title = "Choose a bird",
                        data_live_search = "true",
                        data_show_subtext = "true"
                        })
                </td>
                <td class="form-group">delete</td>               
            </tr>
        </tbody>
    </table>
</form>

任何人都可以就如何呈现每个 selectpicker 提供任何帮助吗?

更新:

如果我删除 bootstrap select,将其保留为普通的 select 列表,一切都会按预期进行。所以这只是让 Bootstrap select 选择器正确呈现的问题。

更新二:

添加另一行的代码是在一个淘汰模型中:

CreateObservationViewModel = function (data) {
var self = this;
ko.mapping.fromJS(data, observedSpeciesMapping, self);

self.addObservedSpecies = function () {
    var observedSpecies = new ObservedSpeciesViewModel({ Id: 0, BirdId: 0, Quantity: 1 });
    self.ObservedSpecies.push(observedSpecies);
}

要使 selectpicker 函数在 knockout 动态添加新的 select 元素时被调用,您需要使用自定义绑定。最简单的情况可能如下所示:

ko.bindingHandlers.selectPicker = {
    init: function (element, valueAccessor, allBindings) {
        $(element).selectpicker('render');
    }
}

将其添加到您的剃须刀下拉列表参数中。它不需要有意义的值,因为它不会对数据做任何事情。

data_bind = "selectPicker: {}, value: BirdId",