Alvaro
Alvaro

Reputation: 41595

Prevent load data again on component change with knockout.js

I'm using components to change between one or another view. That's what I was recommended to do.

Now every time I change between views the data is being loaded again. Here's a reproduction of the issue. (Check the console).

It is not such a big deal in the example I provided but when calling an external API it is a big deal.

How can I avoid that?

And as a related problem, at the moment it is calling the API (or loading the data in my example) twice on load. Once for each registered component. That shouldn't be like that either.

Should I be using jQuery / Javascript to call the API with ajax and then once I have the data set it in the viewmodel?

$.getJSON("/some/url", function(data) { 
    viewModel.setData(data); 
})

Upvotes: 0

Views: 338

Answers (1)

James Thorpe
James Thorpe

Reputation: 32202

The issue is that within your component definitions, you're using the constructor function method of specifying the viewModel for the component, so each time it's using the component, it's actually instantiating an entirely new viewmodel.

And as a related problem, at the moment it is calling the API (or loading the data in my example) twice on load. Once for each registered component. That shouldn't be like that either.

Note that it's calling it once because you called new viewModel() yourself, and once for the initial component being displayed when it's instantiating the extra viewmodel. It's not logged twice because you registered two components - if you register more components, you'll see it's only logged twice still.

A quick fix for you is to use the shared object instance method of specifying the viewModel:

var vm = new viewModel();

ko.components.register('summary', {
    viewModel: {instance: vm},
    template: '...'
});

ko.components.register('details', {
    viewModel: {instance: vm},
    template: '...'
});

ko.applyBindings(vm);

You'll have to decide longer term if this is the right approach for your project as a whole, there are several ways of passing data into components, this is just one of them.

Here's an updated fiddle, that only logs loading data once.

Upvotes: 3

Related Questions