我在KO bindingHandler中使用jquery手风琴,我必须填充手风琴UI使用的DOM,按照app要求使用ajax。
this.faqList = ko.observableArray();
$.ajax({
url: 'getFaqs'
}).done(function( data ) {
that.faqList(data);
});
我的bindingHandler应该像
一样简单ko.bindingHandlers.koAccordion = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
$(element).accordion(valueAccessor());
},
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
$(element).accordion(valueAccessor());
}
};
当observableArray(faqList)发生变化时会调用update方法,但此时UI手风琴需要已经填充的DOM结构,这是不正确的,看起来KO在调用update方法后创建。 在使用新内容填充DOM结构后,如何实现调用更新?
这是默认的DOM。
<ul class="question-list" data-bind="koAccordion: {
active: false,
autoHeight: false,
collapsible: true}">
<!-- ko foreach: faqList -->
<li>
<div class="header">
<span class="rigth-arrow"></span>
<a href="#" data-bind="text: title"></a>
</div>
<div class="content">
<h2 data-bind="text: title"></h2>
<div data-bind="text: content"></div>
</div>
</li>
<!-- /ko -->
</ul>
答案 0 :(得分:3)
koAccordion.update
没用,因为你永远不会更新那个绑定值:它在标记中是静态的,并且不包含任何可观察对象。 foreach
绑定为您的目的提供afterRender
回调:
var vm = function() {
// ...
this.initAccordion = function(element) {
$(element).accordion(accordionOptions);
};
};
<!-- ko foreach: { data: faqList, afterRender: initAccordion } -->
但是,在这种情况下,您必须将accordion选项移出绑定值。如果你坚持使用自定义绑定,一种方法是将工作委托给foreach
绑定,在途中将afterRender
插入绑定值:
ko.bindingHandlers.koAccordion = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel,
bindingContext) {
var newValue = ko.computed(function() {
var value = ko.unwrap(valueAccessor());
value.afterRender = function(element) {
$(element).accordion(value);
};
return value;
});
return ko.bindingHandlers.foreach.init(element, newValue,
allBindingsAccessor, viewModel, bindingContext);
},
update: function(element, valueAccessor, allBindingsAccessor, viewModel,
bindingContext) {
return ko.bindingHandlers.foreach.update(element, valueAccessor,
allBindingsAccessor, viewModel, bindingContext);
}
};
像这样使用它:
<ul class="question-list" data-bind="koAccordion: {
data: faqList,
active: false,
autoHeight: false,
collapsible: true }">
<li>...bindings...</li>
</ul>
请参阅我在帖子中分享的演示页面:http://codepen.io/anon/pen/IJpuj
答案 1 :(得分:1)
This is my final code
ko.bindingHandlers.koAccordion = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var newValue = ko.computed(function() {
var value = ko.unwrap(valueAccessor());
value.afterRender = function(renderedElement, loopEntryObject) {
if ( loopEntryObject == value.data()[value.data().length - 1] ) {
if ($(element).data('accordion')) {
$(element).accordion('destroy');
}
$(element).accordion(value);
}
};
return value;
});
return ko.bindingHandlers.foreach.init(element, newValue, allBindingsAccessor, viewModel, bindingContext);
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
return ko.bindingHandlers.foreach.update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
}