jquery and requirejs and knockout; reference requirejs object from within itself
- by Thomas
We use jquery and requirejs to create a 'viewmodel' like this:
define('vm.inkoopfactuurAanleveren',
['jquery', 'underscore', 'ko', 'datacontext', 'router', 'messenger', 'config', 'store'],
function ($, _, ko, datacontext, router, messenger, config, store) {
var
isBusy = false,
isRefreshing = false,
inkoopFactuur = { factuurNummer: ko.observable("AAA") },
activate = function (routeData, callback) {
messenger.publish.viewModelActivated({ canleaveCallback: canLeave });
getNewInkoopFactuurAanleveren(callback);
var restricteduploader = new qq.FineUploader({
element: $('#restricted-fine-uploader')[0],
request: {
endpoint: 'api/InkoopFactuurAanleveren',
forceMultipart: true
},
multiple: false,
failedUploadTextDisplay: {
mode: 'custom',
maxChars: 250,
responseProperty: 'error',
enableTooltip: true
},
text: {
uploadButton: 'Click or Drop'
},
showMessage: function (message) {
$('#restricted-fine-uploader').append('<div class="alert alert-error">' + message + '</div>');
},
debug: true,
callbacks: {
onComplete: function (id, fileName, responseJSON) {
var response = responseJSON;
},
}
});
},
invokeFunctionIfExists = function (callback) {
if (_.isFunction(callback)) {
callback();
}
},
loaded = function (factuur) {
inkoopFactuur = factuur;
var ids = config.viewIds;
ko.applyBindings(this, getView(ids.inkoopfactuurAanleveren)); /*<----- THIS = OUT OF SCOPE!*/ /
},
bind = function () { },
saved = function (success) {
var s = success;
},
saveCmd = ko.asyncCommand({
execute: function (complete) {
$.when(datacontext.saveNewInkoopFactuurAanleveren(inkoopFactuur))
.then(saved).always(complete);
return;
},
canExecute: function (isExecuting) {
return true;
}
}),
getView = function (viewName) {
return $(viewName).get(0);
},
getNewInkoopFactuurAanleveren = function (callback) {
if (!isRefreshing) {
isRefreshing = true;
$.when(datacontext.getNewInkoopFactuurAanleveren(dataOptions(true))).then(loaded).always(invokeFunctionIfExists(callback));
isRefreshing = false;
}
},
dataOptions = function (force) {
return {
results: inkoopFactuur,
// filter: sessionFilter,
//sortFunction: sort.sessionSort,
forceRefresh: force
};
},
canLeave = function () {
return true;
},
forceRefreshCmd = ko.asyncCommand({
execute: function (complete) {
//$.when(datacontext.sessions.getSessionsAndAttendance(dataOptions(true)))
// .always(complete);
complete;
}
}),
init = function () {
// activate();
// Bind jQuery delegated events
//eventDelegates.sessionsListItem(gotoDetails);
//eventDelegates.sessionsFavorite(saveFavorite);
// Subscribe to specific changes of observables
//addFilterSubscriptions();
};
init();
return {
activate: activate,
canLeave: canLeave,
inkoopFactuur: inkoopFactuur,
saveCmd: saveCmd,
forceRefreshCmd: forceRefreshCmd,
bind: bind,
invokeFunctionIfExists: invokeFunctionIfExists
};
});
On the line ko.applyBindings(this, getView(ids.inkoopfactuurAanleveren)); in the 'loaded' method
the 'this' keyword doens't refer to the 'viewmodel' object.
the 'self' keyword seems to refer to a combination on methods found over multiple 'viewmodels'.
The saveCmd property is bound through knockout, but gives an error since it cannot be found.
How can the ko.applyBindings get the right reference to the viewmodel?
In other words, with what do we need to replace the 'this' keyword int he applyBindings.
I would imagine you can 'ask' requirejs to give us the ealiers instantiated object with identifier 'vm.inkoopfactuurAanleveren' but I cannot figure out how.