Reputation: 37
I'm following this example: http://jsfiddle.net/rniemeyer/mfegm/
JavaScript
// Using jquery-ui-1.11.4.js
// and jquery-1.10.2.js
// Creates a few tags to loop through
var tag = {
UserId: "MuzzyA",
TagText: "This text should be collapsed in an accordion"
};
self.tags.push(new Tag(tag, null));
self.tags.push(new Tag(tag, null));
self.tags.push(new Tag(tag, null));
var Tag = function(tag, comments) {
this.tag = ko.observable(tag);
this.comments = ko.observableArray(comments);
}
CSHTML
<div class="panel-body" data-bind="foreach:tags,accordion: {}">
<h4>
<a href="#" data-bind="text: tag().UserId"></a>
</h4>
<div>
// Content here
</div>
</div>
The result I get from that is just a list, no accordion
I'm not sure what I'm doing wrong.
EDIT: Calling .accordion
function init() {
ko.applyBindings(new ViewModel());
ko.bindingHandlers.accordion = {
init: function (element, valueAccessor) {
var options = valueAccessor() || {};
setTimeout(function () {
$(element).accordion(options);
}, 0);
//handle disposal (if KO removes by the template binding)
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$(element).accordion("destroy");
});
},
update: function (element, valueAccessor) {
var options = valueAccessor() || {};
$(element).accordion("destroy").accordion(options);
}
}
}
Below is how my view model is set up. I can't really change it, because there's an entire system relying on it. This is why it gets binded the way you see
var ViewModel = function () {
var self = this;
self.tags = ko.observableArray();
}
document.addEventListener("DOMContentLoaded", init, false);
function init() {
ko.applyBindings(new ViewModel());
}
Upvotes: 0
Views: 247
Reputation: 43881
applyBindings
can only apply bindings that have been defined. Defining them afterward does not retroactively apply them. I moved the additional binding handler to be defined before the bindings are applied, and I removed the setTimeout, which was allowing the destroys to be called before the accordion was set up.
var Tag = function(tag, comments) {
this.tag = ko.observable(tag);
this.comments = ko.observableArray(comments);
}
var tag = {
UserId: "MuzzyA",
TagText: "This text should be collapsed in an accordion"
};
var ViewModel = function() {
var self = this;
self.tags = ko.observableArray();
self.tags.push(new Tag(tag, null));
self.tags.push(new Tag(tag, null));
self.tags.push(new Tag(tag, null));
}
document.addEventListener("DOMContentLoaded", init, false);
function init() {
ko.bindingHandlers.accordion = {
init: function(element, valueAccessor) {
var options = valueAccessor() || {};
$(element).accordion(options);
//handle disposal (if KO removes by the template binding)
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$(element).accordion("destroy");
});
},
update: function(element, valueAccessor) {
var options = valueAccessor() || {};
$(element).accordion("destroy").accordion(options);
}
}
ko.applyBindings(new ViewModel());
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>
<div class="panel-body" data-bind="foreach:tags,accordion: {}">
<h4>
<a href="#" data-bind="text: tag().UserId"></a>
</h4>
<div>
// Content here
</div>
</div>
Upvotes: 1