Accessing the viewmodel from an external javascript file

508 views
Skip to first unread message

kwakwa...@gmail.com

unread,
Oct 21, 2013, 5:28:10 AM10/21/13
to knock...@googlegroups.com
Hi all,

I'm trying to separate as much of my javascript into an external file as I've noticed a lot of it is repeating. One feature that lies across most of my interface is the 'search' which I use with viewmodel (http://coderenaissance.github.io/knockout.viewmodel/).

The viewmodel variable name created from ko.viewmodel.fromModel might be different on each page, but I need to access it to updateFromModel. I've had a look around and I think ko.contextFor(this) is what I'm after but I want to make sure if it's doing what I'm expecting.

body.html

var myViewModel = ko.viewmodel.fromModel(myViewData, {
  extend
: {
   
"{root}.messages[i]": function(item) {
       
// ...
   
},
 
}
});

external.js

$('#search-json').on('input', function() {
 
var viewModel = ko.contextFor(this);
 
var search_by = $('#search-by').attr('data-search-by');
 
var url       = search_url + "?" + search_by + "_startsWith=" + $(this).val();
 
// load in message data using our API and this search term
  $
.getJSON(url, function(data) {
     
// create observable properties for each of the resource keys from data
      ko
.viewmodel.updateFromModel(viewModel.$data, data);
 
});
});

I can then reduce the only global variable to 'search_url'.

If this is the way to refer to the observable, will that also mean I can also separate out my actions? Something like the following (which is currently in body.html):

  $('#action-delete').click(function() {
    ko
.utils.arrayForEach(myViewModel.people(), function(item) {
     
if (item.isSelected()) {
        myViewModel
.people.Delete(item);
     
}
   
});
 
});

Would be fine as:

  $('#action-delete').click(function() {
   
var viewModel = ko.contextFor(this);
    ko
.utils.arrayForEach(viewModel.$data, function(item) {
     
if (item.isSelected()) {
        viewModel
.$data.Delete(item);
     
}
   
});
 
});


Cheers,
-Paul

Gunnar Liljas

unread,
Oct 21, 2013, 5:24:11 PM10/21/13
to knock...@googlegroups.com
Could you present some examples of this reuse? How much duplication is there?

kwakwa...@gmail.com

unread,
Oct 22, 2013, 3:17:39 AM10/22/13
to knock...@googlegroups.com
How do you mean? You'd like to see a full working example?

The duplication across the interface I'm creating is basically the search and a few of the bulk actions (#action-delete, #action-select-all). It makes sense for me to separate this out into an external javascript file, and not rely on the global viewmodel variable name.

I suppose my question boils down to is is ko.contextFor(this); the correct way to get the model from within a jquery action, and update the observables with new data using the binding context $data (viewModel.$data)? I wasn't sure if this was the suggested way is all because I cannot see any examples of its use.

$('#action-get-weather').on('click', function() {
 
var viewModel = ko.contextFor(this);
 
var url       = "http://api.openweathermap.org/data/2.5/weather?q=London,uk";
  $
.getJSON(url, function(data) {
      ko
.viewmodel.updateFromModel(viewModel.$data, data);
 
});
});

(I know the above won't work because of the SOP, just a proof of concept :))
Reply all
Reply to author
Forward
0 new messages