Reputation: 159
Can I create an observableArray inside init block in the custom binding? Also, I want to use this observableArray inside update method to push some new elements.
it to loop For example:
ko.bindingHandlers.yourBindingName = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var animateImageArray = ko.observableArray(["img1", "img2"]);
ko.applyBindings(animateImageArray);
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
//Also can I get a reference to animateImageArray here
}
};
HTML
<div class="customized-slider-wrapper" data-bind="yourBindingName: someData">
<div class="customized-slider" data-bind="foreach: animateImageArray">
<div class="individual-tile">
<img data-bind= "attr: {src: $data}" />
</div>
</div>
</div>
Edits:
Tried the below code in comment
StopAnimation = setInterval(function () {
_index++;
if (_index >= imgArray.length) {
_index = 0;
}
$(temp[_index]).attr('src', imgArray[_index]);
toBeScrolledBy = slideWidth * _index;
$(scroller).css({
'transform': 'translateX(-' + toBeScrolledBy + 'px)'
});
}, 1500);
Now the sequence the images animates gets wrong. The first image slides and second loads, the the animation gets back to first instead of third and it happens every time a new index is passed in the image src array.
Upvotes: 0
Views: 181
Reputation: 1074038
From what you've described, init
shouldn't be creating the array, and the array probably doesn't have to be observable. Instead, your observable array of products would contain objects, and each product object would have an array (probably doesn't have to be observable) of its images. Rough sketch:
var vm = {
products: ko.observableArray([
{
name: "Widget",
images: [
"https://via.placeholder.com/100/5d5/fff.png?text=Widget+1",
"https://via.placeholder.com/100/d55/fff.png?text=Widget+2",
"https://via.placeholder.com/100/55d/fff.png?text=Widget+3"
]
},
{
name: "Gadget",
images: [
"https://via.placeholder.com/100/55d/fff.png?text=Gadget+1",
"https://via.placeholder.com/100/5d5/fff.png?text=Gadget+2",
"https://via.placeholder.com/100/d55/fff.png?text=Gadget+3",
"https://via.placeholder.com/100/55d/fff.png?text=Gadget+4",
"https://via.placeholder.com/100/5d5/fff.png?text=Gadget+5"
]
},
])
};
ko.bindingHandlers.productSlides = {
init: function(element, valueAccessor) {
// Current timer handle
var timer = 0;
// Current slide index
var index = 0;
// Show first slide
element.src = ko.unwrap(valueAccessor())[index];
// Set up handlers
element.addEventListener("mouseenter", startTimer);
element.addEventListener("mouseleave", clearTimer);
// Show next slide
function nextSlide() {
// Re-read the observable in case it's changed
var slides = ko.unwrap(valueAccessor());
index = (index + 1) % slides.length;
element.src = slides[index];
}
// Start showing slides
function startTimer() {
if (!timer) {
nextSlide();
timer = setInterval(nextSlide, 1000);
}
}
// Stop showing slides
function clearTimer() {
if (timer) {
clearInterval(timer);
timer = 0;
}
}
// Clean up on disposal
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
element.removeEventListener("mouseenter", startTimer);
element.removeEventListener("mouseleave", clearTimer);
clearTimer();
});
}
};
console.log("Showing products");
ko.applyBindings(vm, document.body);
// Example of adding another product to the array later
setTimeout(function() {
console.log("Adding third product");
vm.products.push({
name: "Doogle",
images: [
"https://via.placeholder.com/100/d55/fff.png?text=Doogle+1",
"https://via.placeholder.com/100/5d5/fff.png?text=Doogle+2",
"https://via.placeholder.com/100/55d/fff.png?text=Doogle+3",
"https://via.placeholder.com/100/d55/fff.png?text=Doogle+4"
]
});
}, 2000);
<div data-bind="foreach: products">
<img data-bind="productSlides: images">
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
Upvotes: 3