不同敲除组件之间的转换 [英] Transitions between different knockout components

查看:132
本文介绍了不同敲除组件之间的转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图应用 CSS 转换,因为我在切换组件之间切换,但我没有太多的快乐实现这一点。基本上我想有一个固定宽度的 div ,但其内部内容将改变。



  ko.components.register {viewModel:function(vm){this.items = vm.value.items;},template:'< div class =big boxdata-bind =foreach:items>< p class = data-bind =text:name>< / p>< / div>'}); ko.components.register(small,{viewModel:function(vm){this.items = vm。 value.items;},template:'< div class =small boxdata-bind =foreach:items>< span class =itemdata-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 );} 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>   

所以我问了一些含糊的关联为什么不应用CSS转换?我知道DOM正在重新构建新值(在这种情况下是新模板),因此CSS转换不适用。



这里的解决方案很简单(确保你重复绑定到同一个东西)。但对于组件,我真的不想将两个模板组合在一起,所以我可以获得转换。有没有其他方法可以实现这个?

解决方案

实际上切换组件意味着DOM被重构,所以我没有看到一个方法使用CSS动画。



你可以做的是构建自己的绑定处理程序,使用Javascript动画:



  ko.bindingHandlers.animatingComponent = {init:function(element,valueAccessor,allBindings,viewModel,bindingContext){var value = valueAccessor var componentName = value.name; //创建一个新的observable,所以我们可以延迟ko的组件//绑定构建新的组件var actualComponentName = ko.observable(componentName()); componentName.subscribe(function(newComponent){$(element).hide(500,function(){actualComponentName(newComponent); $(element).show(500);});}); ko.bindingHandlers.component.init(element,function(){return {name:actualComponentName,params:value.params};},allBindings,viewModel,bindingContext); }}; ko.components.register(big,{viewModel:function(vm){this.items = vm.value.items;},template:'< div class =big boxdata-bind = foreach:items>< p class =itemdata-bind =text:name>< / p>< / div>'}); ko.components.register(small,{ viewModel:function(vm){this.items = vm.value.items;},template:'< div class =small boxdata-bind =foreach:items>< span class =item data; 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;}。big {border:thin solid black;} small {border:thin solid black; padding:10px 10px 10px 10px;}。item {padding-left:10px;}  

 < script src =https://code.jquery.com/jquery-1.11.3.min.js>< / script>< script src =https:// cdnjs .cloudflare.com / ajax / libs / knockout / 3.2.0 / knockout-min.js>< / script>< div data-bind =animatingComponent:{name:componentName,params:{value:$ data }}>< / div>  


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?

解决方案

You're actually switching the component meaning the DOM is being re-constructed, so I don't see a way to animate using CSS.

What you can do is build your own binding handler which does the animating for you using Javascript:

ko.bindingHandlers.animatingComponent = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        var value = valueAccessor();
        var componentName = value.name;
        // create a new observable so we can delay the moment ko's component 
        // binding builds the new component
        var actualComponentName = ko.observable(componentName());
        componentName.subscribe(function(newComponent) {
            $(element).hide(500, function() {
                actualComponentName(newComponent);
                $(element).show(500);
           });
        });

        ko.bindingHandlers.component.init(element, function() { 
            return { name: actualComponentName, params: value.params}; 
        }, allBindings, viewModel, bindingContext);
    }
};

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;
}
.big {
    border: thin solid black;
}
.small {
    border: thin solid black;
    padding: 10px 10px 10px 10px;
}
.item {
    padding-left: 10px;
}

<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="animatingComponent: { name: componentName, params: { value: $data } }">
</div>

这篇关于不同敲除组件之间的转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆