Подтвердить что ты не робот

Загрузочный опрос с knockout.js

У меня есть приложение, получающее некоторые данные через AJAX-вызов. После этого полученные данные привязываются к DOM-элементам, используя библиотеку knockout.js. Я бы хотел использовать ненавязчивую разметку boostrap для создания таких всплывающих окон:

<table class="table table-condensed" data-bind="foreach: items">
    <tr>
        <td><b data-bind="text: $data.id"></b></td>
        <td data-bind="text: $data.title"></td>
        <td><a href="#" rel="popover" data-bind="attr: {title: $data.info}" data-placement="top">Info</a></td>
    </tr>
</table>

Согласно последней документации для начальной загрузки, неявный вызов чего-то типа $('.popover').popover() не требуется, однако он не работает.

Я полагаю, что boostrap.js выполняют некоторый DOM-анализ на document.ready и выполняют всю необходимую работу для popover для работы. И вопрос: есть ли способ сказать bootstrap.js выполнить аналогичное задание для данных после получения ответа AJAX? Или как можно достичь такого рода требований?

4b9b3361

Ответ 1

Вы можете создать пользовательское привязку данных, чтобы сделать этот элемент popover. Проверьте jsfiddle demo

ko.bindingHandlers.bootstrapPopover = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
        var options = ko.utils.unwrapObservable(valueAccessor());
        var defaultOptions = {};        
        options = $.extend(true, {}, defaultOptions, options);
        $(element).popover(options);
    }
};

var viewModel = {

    items: ko.observableArray([{
        "id": 1,
        "title": "title-1",
        "info": "info-1"},
    {
        "id": 2,
        "title": "title-2",
        "info": "info-2"},
    {
        "id": 3,
        "title": "title-3",
        "info": "info-3"}])

}

ko.applyBindings(viewModel);​

И html

<div class="container">
    <div class="hero-unit">     
        <table class="table table-condensed" data-bind="foreach: items">
            <tr>
                <td><b data-bind="text: $data.id"></b></td>
                <td data-bind="text: $data.title"></td>
                <td><a href="#" data-bind="bootstrapPopover : {content : $data.info  }">Info</a></td>
            </tr>
        </table>
    </div>
</div>​

Ответ 2

"Согласно последней документации для начальной загрузки, неявный вызов чего-то типа $('. popover'). popover() не требуется, однако он не работает."

Я не могу найти нигде в документах, которые это утверждают. На самом деле, они говорят об обратном. А именно, Twitter Bootstrap делает не автоматически инициализировать popovers или всплывающие подсказки на странице. Из документов:

По соображениям производительности, всплывающая подсказка и popover data-apis выбирают. Если вы хотите использовать их, просто укажите вариант выбора.

Чтобы "выбрать", как говорится, вы присоедините объект Popover к элементу, который содержит все всплывающие окна, которые могут отображаться на странице. Вот один из способов сделать это:

$('body').popover({selector: '[rel="popover"]'});

Я полагаю, что соображения производительности, которые были изначально учтены, исходили из того, что до 2.1 плагин Popover по умолчанию запускался событиями mouseenter и mouseleave, которые, безусловно, не то, что вы хотите постоянно обрабатывать для всей страницы.

Начиная с версии 2.1, по умолчанию теперь нажмите, что не должно вызывать проблем с производительностью. Тем не менее, если вы можете определить элемент дальше DOM, чем body, к которому нужно прикрепить объект Popover, это всегда является предпочтительным. Однако, в зависимости от того, где вы показываете контент AJAX, body может быть лучшим выбором.

Ответ 3

Вот полный рабочий пример с массивом объектов, я изменил ko.applyBindings() на ko.applyBindingsToDescendants, чтобы включить контекст привязки $root и $parent, когда мы хотели бы связать кнопку, например, с функцией в корне ViewModel.

$(element).click(function() {
            $(this).popover('toggle');
            var thePopover = document.getElementById(attribute.id+"-popover");
            childBindingContext = bindingContext.createChildContext(viewModel);
            ko.applyBindingsToDescendants(childBindingContext, thePopover);
    });

Посмотрите @http://jsfiddle.net/mounir/Mv3nP/6/