I'm trying to apply CSS
transitions as I switch between knockout components but I'm not having much joy in achieving this. Essentially I want to have a div
with a fixed width, but the internal content of which will change. As it does this I want to be able to transition the re-sizing of the element.
ko.components.register("big", {
viewModel: function (vm) {
this.items = vm.value.items;
},
template: '<div class="big box" data-bind="foreach: items"><p class="item" data-bind="text: name"></p></div>'
});
ko.components.register("small", {
viewModel: function (vm) {
this.items = vm.value.items;
},
template: '<div class="small box" data-bind="foreach: items"><span class="item" data-bind="text: name"></span></div>'
});
var vm = {};
vm.componentName = ko.observable("small");
vm.items = ko.observableArray([{ name: "A" }, { name: "B" }, { name: "C" }]);
ko.applyBindings(vm);
setInterval(function() {
if(vm.componentName() === "small") { vm.componentName("big"); }
else { vm.componentName("small"); }
}, 3000);
.box {
width: 200px;
-webkit-transition: height 2s;
transition: height 2s;
-webkit-transition: width 2s;
transition: width 2s;
}
.big {
border: thin solid black;
}
.small {
border: thin solid black;
padding: 10px 10px 10px 10px;
}
.item {
padding-left: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="component: { name: componentName, params: { value: $data } }">
</div>
So I've asked something vaguely related Why doesn't CSS transition get applied? where I learnt that the DOM is being re-constructed for the new value (in this case new template) and hence CSS transitions don't apply.
The solution there was simple (ensure you bind to the same thing repeatedly). But for components, I really don't want to combine two templates together just so I can get transitions. Is there another way I can achieve this?