5
votes

I am trying to build a single page application using Vue.js 2.0. The application is supposed to feature multiple modes of operation, which I wanted to implement using Vue.js dynamic component. Since the state of each mode should be preserved while switching between them, I decided to use the keep-alive feature that Vue.js provides. One of the modes is supposed to be a network view created by using Cytoscape.js .

And here comes my problem. The network is initialized correctly when I switch the first time to it, but after switching back and forth, the network view freezes. keep-alive works properly (as far as I understand it) and brings back both the Cytoscape instance and the proper HTML section. Somehow, the connection between the Cytoscape instance and the HTML sections seems to be lost, although I don't understand how and why.

Here is an example code.

//sample data for network
var testElements = [
    { data: {id: 'a'} },
    { data: {id: 'b'} },
    { data: {
        id: 'ab',
        source: 'a',
        target: 'b' 
        }
    }
];
    
//Vue components
Vue.component('otherView', {
    template: '<div>This is another mode</div>'
});

Vue.component('network', {
    template: '<div id="container" class="cy"></div>',
    mounted: function () {
        cy1 = cytoscape({
            container: document.getElementById("container"),
            elements: testElements
        });
    }
});

//Vue dynamic component
var vm = new Vue({
    el: "#dynamic",
    data: {
        currentView: 'otherView'
    }
});
.cy {
    width: 500px;
    height: 500px;
    position: absolute;
    top: 100px;
    left: 10px;
}
<script src="https://rawgit.com/cytoscape/cytoscape.js/master/dist/cytoscape.js"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>

<div id="dynamic" >
    <div id="selectorButton">
        <button id="button1" @click="currentView='otherView'">Other view</button>
        <button id="button2" @click="currentView='network'">Network</button>
    </div>

    <keep-alive>
        <component :is="currentView"></component>
    </keep-alive>

</div>
2

2 Answers

0
votes

If you remove a Cytoscape instance, you've destroyed it. Either make sure that Vue doesn't destroy your DOM elements or create a new Cytoscape instance each time from JSON: http://js.cytoscape.org/#cy.json

0
votes

I could not understand your problem completely , but you can try shifting code you have written in network component's mounted oroperty to activated property as follows

    Vue.component('network', {
        template: '<div id="container" class="cy"></div>',
        activated: function () {
            if(initial state){
                cy1 = cytoscape({
                    container: document.getElementById("container"),
                    elements: testElements
                });
            }

        }
    }); 

This may help because when a cmponent is kept-alive the mounted hook is called only once when first time enter you the component, its not called again on subsequent entering whereas activated hook is called everytime you enter the component when kept-alive