[英]Collapsable panel with bootstrap and knockout
我不能用KnockoutJS和Bootstrap制作手风琴才能正常工作。 我这样定义它:
<div class="panel-group" id="accordion" data-bind="foreach: Advertisers()">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<span data-toggle="collapse" data-bind="html: $data, attr: { 'data-target': '#' + $data }"></span>
</h4>
</div>
</div>
<div class="panel-collapse collapse" data-parent="#accordion" data-bind="attr: { id: $data }">
<div class="panel-body">
...content...
“广告商”是一个可观察的字符串数组,因此$ data是一个字符串。 我为每个广告客户提供了一个“行”。
所有行最初都会折叠,单击一行会展开下面的内容。 到现在为止还挺好。
问题是,当我点击另一行时,我预计之前的扩展会崩溃,但这种情况并没有发生。 (无论是使用Bootstrap还是KnockoutJS,我都无法工作!)
编辑了代码。
如何简单的自定义绑定,它还允许您稍微整理您的视图:
ko.bindingHandlers.bootstrapAccordion = {
init: function(elem, value, allBindings) {
var options = ko.utils.unwrapObservable(value()),
handleClass = '[data-toggle]',
contentClass = '.collapse',
openItem = ko.utils.unwrapObservable(options.openItem) || false,
itemClass = '.' + ko.utils.unwrapObservable(options.item) || '.accordion-group',
items = $(elem).find(contentClass);
// toggle: false required to hide items on load
items.collapse({ parent: elem, toggle: false });
if (openItem > -1) items.eq(openItem).collapse('show');
// if the array is dynamic, the collapse should be re-initiated to work properly
var list = allBindings.get('foreach');
if (ko.isObservable(list)) {
list.subscribe(function() {
$(elem).find(contentClass).collapse({ parent: elem, toggle: false });
});
}
$(elem).on('click', handleClass, function() {
$(elem).find(contentClass).collapse('hide');
$(this).closest(itemClass).find(contentClass).collapse('show');
});
}
};
此绑定需要2个参数(容器的className,以及可选的,在加载时打开的项),例如: bootstrapAccordion: {item: 'panel-group', openItem: 0}
,并且应该设置在具有foreach
绑定。 它假定可折叠部分具有collapse
类,并且用于切换它们的句柄具有data-toggle
属性。
在这里看到它: http : //jsfiddle.net/pkvn79h8/22/
我扩展了Tyblitz上面的示例,包括支持更改图标(例如,+ / - ,上/下箭头),并支持通过将data-open-next属性应用于任何应该移动到下一个面板的点击来移动到下一个面板。
ko.bindingHandlers.bootstrapAccordion = {
init: function (elem, value, allBindings) {
var options = ko.utils.unwrapObservable(value()),
handleClass = '[data-toggle]',
contentClass = '.collapse',
openedClass = ko.utils.unwrapObservable(options.openedClass) || 'fa-minus',
closedClass = ko.utils.unwrapObservable(options.closedClass) || 'fa-plus',
openCloseToggleClasses = openedClass + ' ' + closedClass,
openItem = ko.utils.unwrapObservable(options.openItem) || false,
itemClass = '.' + (ko.utils.unwrapObservable(options.item) || 'accordion-group'),
items = $(elem).find(contentClass);
var initializeItems = function(items) {
// toggle: false required to hide items on load
items.collapse({ parent: elem, toggle: false });
if (openItem > -1) {
items.eq(openItem).collapse('show');
items.eq(openItem).closest(itemClass).find('.panel-heading').find('i').toggleClass(openCloseToggleClasses);
items.eq(openItem).closest(itemClass).find('.panel-heading').addClass('active');
}
}
initializeItems(items);
// if the array is dynamic, the collapse should be re-initiated to work properly
var list = allBindings.get('foreach');
if (ko.isObservable(list)) {
list.subscribe(function () {
initializeItems($(elem).find(contentClass));
});
}
$(elem).on('click', handleClass, function () {
$(elem).find(contentClass).collapse('hide');
$(this).closest(itemClass).find(contentClass).collapse('show');
$(this).closest(itemClass).parent().find('.panel-heading i').removeClass(openCloseToggleClasses);
$(this).closest(itemClass).parent().find('.panel-heading i').addClass(closedClass);
$(this).closest(itemClass).parent().find('.panel-heading').removeClass('active');
if ($(this).closest(itemClass).find('.panel-collapse').attr('aria-expanded') === "true") {
$(this).closest(itemClass).find('.panel-heading i').toggleClass(openCloseToggleClasses);
$(this).closest(itemClass).find('.panel-heading').addClass('active');
}
});
$(elem).on('click', '[data-open-next]', function () {
$next = $(this).closest(itemClass).next(itemClass).find(handleClass);
if ($next.length) {
$next.click();
} else {
$same = $(this).closest(itemClass).find(contentClass);
$same.collapse('hide');
$same.parent().find('.panel-heading i').removeClass(openCloseToggleClasses);
$same.parent().find('.panel-heading i').addClass(closedClass);
$same.parent().find('.panel-heading').removeClass('active');
}
});
}
};
用于此绑定的示例标记:
<div data-bind="foreach: listOfThings, bootstrapAccordion: { openItem: 0 }">
<div class="accordion-group">
<div class="panel panel-default" style="cursor: pointer;" data-toggle>
<div class="panel-heading">
<i class="fa fa-plus fa-pull-left fa-2x"></i>
<h3 data-bind="text: name">Title of expander</h3>
</div>
</div>
<div class="panel-collapse collapse">
<div class="panel-body">
<div class="clearfix" data-accordion-content>
<!-- content goes here -->
<!-- ko if: $index() < $parent.listOfThings().length -1 -->
<button data-open-next>Next Thing</button>
<!-- /ko -->
</div>
</div>
</div>
</div>
</div>
我会感觉不好不回馈:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.