Slick.js 带有 Knockout 自定义绑定的轮播
Slick.js carousel with Knockout custom binding
我想使用漂亮的旋转木马(http://kenwheeler.github.io/slick/) with Knockout. After looking at some of the other questions () it seems like the way to go would be to use a custom binding, but I'm having trouble getting it to load properly - it seems like the slick carousel is initializing before the DOM has completely loaded so it doesn't connect the last slide to the first slide. I also looked at knockout js custom binding called after internal dom elements rendered 并且正在尝试使用子绑定上下文让自定义绑定强制子元素先绑定。
这是 html 标记:
<div data-bind = "slick">
<!-- ko foreach: results -->
<div>
<result-thumbnail params="result:$data"></result-thumbnail>
</div>
<!-- /ko -->
</div>
result-thumbnail 是一个单独的剔除组件,用于格式化我想在轮播中呈现的数据。在自定义绑定文件中:
ko.bindingHandlers.slick = {
init: function(element, valueAccessor, allBindingsAccessor, data, bindingContext) {
var options = {
infinite:true,
slidesToShow: 3,
slidesToScroll: 1,
};
var childBindingContext = bindingContext.createChildContext(
bindingContext.$rawData,
null,
function(context) {
ko.utils.extend(context, valueAccessor());
});
ko.applyBindingsToDescendants(childBindingContext, element);
var local = ko.utils.unwrapObservable(valueAccessor());
ko.utils.extend(options, local);
$(element).slick(options);
return { controlsDescendantBindings: true };
},
update: function(element, valueAccessor, allBindingsAccessor, data, context) {
}
};
我正在考虑的几件事:
- 我应该将光滑的初始化移动到更新功能吗?
- 我编写的巧妙的自定义绑定是否需要绑定到不同的元素?
- 如果我正在更改 results
observable 的值,我是否需要通过破坏然后重新创建轮播来更新 slick?
如有任何帮助,我们将不胜感激!我仍在学习自定义绑定,如果有人有过让 slick carousel 与 Knockout 一起工作的经验,那也很高兴听到。
免责声明:我从未使用过slick.js。
您认为轮播在 DOM 完全加载之前正在初始化是正确的。
如果您在 Whosebug 上搜索,您会发现许多关于如何在所有元素都完成渲染后调用函数的选项 - 我最喜欢的选项如下所述:.
一旦你有了这样的回调,你就可以使用它在你的主 viewModel 中设置一个 observable 为 true
,像这样:
var allElementsRendered = ko.observable(false);
var yourAfterRenderFunction = function () {
allElementsRendered(true);
}
然后您可以将该可观察对象作为参数传递给您的 'slick' 绑定,如下所示:
<div data-bind = "slick: allElementsRendered">
每当 allElementsRendered() 可观察值发生变化时,将调用自定义绑定中的 'update' 函数 - 因此只需将初始化逻辑移动到那里,如下所示:
update: function(element, valueAccessor, allBindingsAccessor, data, context) {
var shouldInit = ko.unwrap(valueAccessor());
if (shouldInit) {
var options = {
infinite:true,
slidesToShow: 3,
slidesToScroll: 1,
};
$(element).slick(options);
} else {
$(element).slick("unslick");
}
}
处理更新结果 observableArray 可能需要一些额外的工作 - 您可以做的是订阅它并在它发生变化时将 allElementsRendered() 设置为 false,如下所示:
var resultsSubscription = results.subscribe(function(newValue){
allElementsRendered(false);
})
这与上面提到的 afterRenderFunction 相结合应该有望使您的旋转木马保持更新。
我想使用漂亮的旋转木马(http://kenwheeler.github.io/slick/) with Knockout. After looking at some of the other questions () it seems like the way to go would be to use a custom binding, but I'm having trouble getting it to load properly - it seems like the slick carousel is initializing before the DOM has completely loaded so it doesn't connect the last slide to the first slide. I also looked at knockout js custom binding called after internal dom elements rendered 并且正在尝试使用子绑定上下文让自定义绑定强制子元素先绑定。
这是 html 标记:
<div data-bind = "slick">
<!-- ko foreach: results -->
<div>
<result-thumbnail params="result:$data"></result-thumbnail>
</div>
<!-- /ko -->
</div>
result-thumbnail 是一个单独的剔除组件,用于格式化我想在轮播中呈现的数据。在自定义绑定文件中:
ko.bindingHandlers.slick = {
init: function(element, valueAccessor, allBindingsAccessor, data, bindingContext) {
var options = {
infinite:true,
slidesToShow: 3,
slidesToScroll: 1,
};
var childBindingContext = bindingContext.createChildContext(
bindingContext.$rawData,
null,
function(context) {
ko.utils.extend(context, valueAccessor());
});
ko.applyBindingsToDescendants(childBindingContext, element);
var local = ko.utils.unwrapObservable(valueAccessor());
ko.utils.extend(options, local);
$(element).slick(options);
return { controlsDescendantBindings: true };
},
update: function(element, valueAccessor, allBindingsAccessor, data, context) {
}
};
我正在考虑的几件事:
- 我应该将光滑的初始化移动到更新功能吗?
- 我编写的巧妙的自定义绑定是否需要绑定到不同的元素?
- 如果我正在更改 results
observable 的值,我是否需要通过破坏然后重新创建轮播来更新 slick?
如有任何帮助,我们将不胜感激!我仍在学习自定义绑定,如果有人有过让 slick carousel 与 Knockout 一起工作的经验,那也很高兴听到。
免责声明:我从未使用过slick.js。
您认为轮播在 DOM 完全加载之前正在初始化是正确的。
如果您在 Whosebug 上搜索,您会发现许多关于如何在所有元素都完成渲染后调用函数的选项 - 我最喜欢的选项如下所述:.
一旦你有了这样的回调,你就可以使用它在你的主 viewModel 中设置一个 observable 为 true
,像这样:
var allElementsRendered = ko.observable(false);
var yourAfterRenderFunction = function () {
allElementsRendered(true);
}
然后您可以将该可观察对象作为参数传递给您的 'slick' 绑定,如下所示:
<div data-bind = "slick: allElementsRendered">
每当 allElementsRendered() 可观察值发生变化时,将调用自定义绑定中的 'update' 函数 - 因此只需将初始化逻辑移动到那里,如下所示:
update: function(element, valueAccessor, allBindingsAccessor, data, context) {
var shouldInit = ko.unwrap(valueAccessor());
if (shouldInit) {
var options = {
infinite:true,
slidesToShow: 3,
slidesToScroll: 1,
};
$(element).slick(options);
} else {
$(element).slick("unslick");
}
}
处理更新结果 observableArray 可能需要一些额外的工作 - 您可以做的是订阅它并在它发生变化时将 allElementsRendered() 设置为 false,如下所示:
var resultsSubscription = results.subscribe(function(newValue){
allElementsRendered(false);
})
这与上面提到的 afterRenderFunction 相结合应该有望使您的旋转木马保持更新。