Hans Karlsen (talk | contribs) No edit summary |
(Automatically adding template at the end of the page.) |
||
(9 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
When working with EXT_Components and integrating towards other services, you may end up in situations where you get callbacks in client-side javascript - and you will want to catch data from such a callback. | |||
To get hold of your objects from such a callback (that are outside of the normal | To get hold of your objects from such a callback (that are outside of the normal Angular realm where you have some scope information at hand), you can do this: | ||
var vmroot=angular.element('#viewmodelWrapper').controller().$scope.ViewModelRoot; | var vmroot=angular.element('#viewmodelWrapper').controller().$scope.ViewModelRoot; | ||
You now have the current local representation of your ViewModel in the vmroot variable and you can set properties like this: | You now have the current local representation of your ViewModel in the vmroot variable and you can set properties like this: | ||
vmroot.MyViewModelColumn=somevalueFromACallBack; | vmroot.MyViewModelColumn=somevalueFromACallBack; | ||
MDrivenTurnkey sees the property you change and handles signaling of server and binding of UI. | MDrivenTurnkey sees the property you change and handles the signaling of the server and binding of UI. | ||
With some defensive error checking: | With some defensive error checking: | ||
Line 15: | Line 15: | ||
return undefined; | return undefined; | ||
} | } | ||
=== Alternative Approach === | |||
Depending on what your needs are, it may be better to inject the result into a UI control and let AngularJS handle the databinding to move that data into the underlying ViewModel-object-column-property (then Turnkey will discover the change and stream it to the server). To let AngularJS know that the code you use to set the value should be handled as a user interaction of the input, you must dispatch the change event. Something like this: | |||
function setResult(label, result) { | |||
let someelem=document.getElementById('BiljettCheck.Id'); // find the input elem bound to ViewModel "BiljettCheck" and Column "Id" | |||
someelem.value=result; // assign a new value to the input | |||
var event = new Event('change'); | |||
someelem.dispatchEvent(event); // signal to listeners (angularjs) that the value has changed | |||
} | |||
=== Acting after Angular Page Has Fully Loaded === | |||
The script below can be added to your page and will call a function StartTheProcess after the data has been bound in Angular (data need not have been downloaded - but it is bound by AngularJS) | |||
angular.element(function () { | |||
console.log('page loading completed'); | |||
startTheProcess(); | |||
}); | |||
You can then use AngularJS functions like $watch to find out when data is available or changed like this (this example was taken from a bank integration for EasyArr - Swedbank): | |||
<pre> | |||
var initiated=false; | |||
function startTheProcess() { | |||
console.log('startTheProcess'); | |||
//debugger; | |||
var thescope=angular.element('#viewmodelWrapper').controller().$scope; | |||
if (!initiated){ | |||
initiated=true; | |||
thescope.$watch('ViewModelRoot.DataIsLoaded', function (newv, oldval, thescope) { | |||
console.log('startTheProcess WATCH DataIsLoaded '+newv); | |||
if (newv=="DataIsLoaded"){ | |||
thescope.ViewClient.CallServerAction('SwedbankPay','SCRIPTSCALLCheckIn',null); // handles the case when we called CheckIn too early | |||
} | |||
}); | |||
thescope.$watch('ViewModelRoot.FetchedScriptUrlForCheckin', function (newv, oldval, thescope) { | |||
console.log('startTheProcess WATCH FetchedScriptUrlForCheckin '+newv); | |||
if (newv && newv!=""){ | |||
DoCheckInScript(newv,thescope); | |||
} | |||
}); | |||
thescope.$watch('ViewModelRoot.FetchedScriptUrlForPaymentUI', function (newv, oldval, thescope) { | |||
console.log('startTheProcess WATCH FetchedScriptUrlForPaymentUI '+newv); | |||
if (newv && newv!=""){ | |||
DoPaymentUIScript(newv,thescope); | |||
} | |||
}); | |||
thescope.$watch('ViewModelRoot.ConsumerId', function (newv, oldval, thescope) { | |||
console.log('startTheProcess WATCH ConsumerId '+newv); | |||
if (newv && newv!=""){ | |||
DoPaymentOrderForThisConsumerProfile(newv,thescope); | |||
} | |||
}); | |||
} | |||
else{ | |||
console.log('startTheProcess - init skipped'); | |||
} | |||
thescope.ViewClient.CallServerAction('SwedbankPay','SCRIPTSCALLCheckIn',null) | |||
console.log('startTheProcess CheckIn'); | |||
} | |||
</pre> | |||
[[Category:Debugging]] | |||
{{Edited|July|12|2024}} |
Latest revision as of 15:34, 10 February 2024
When working with EXT_Components and integrating towards other services, you may end up in situations where you get callbacks in client-side javascript - and you will want to catch data from such a callback.
To get hold of your objects from such a callback (that are outside of the normal Angular realm where you have some scope information at hand), you can do this:
var vmroot=angular.element('#viewmodelWrapper').controller().$scope.ViewModelRoot;
You now have the current local representation of your ViewModel in the vmroot variable and you can set properties like this:
vmroot.MyViewModelColumn=somevalueFromACallBack;
MDrivenTurnkey sees the property you change and handles the signaling of the server and binding of UI.
With some defensive error checking:
function GetVMRoot(){ var ctrl=angular.element('#viewmodelWrapper').controller(); if (ctrl !== undefined){ return ctrl.$scope.ViewModelRoot; } return undefined; }
Alternative Approach
Depending on what your needs are, it may be better to inject the result into a UI control and let AngularJS handle the databinding to move that data into the underlying ViewModel-object-column-property (then Turnkey will discover the change and stream it to the server). To let AngularJS know that the code you use to set the value should be handled as a user interaction of the input, you must dispatch the change event. Something like this:
function setResult(label, result) { let someelem=document.getElementById('BiljettCheck.Id'); // find the input elem bound to ViewModel "BiljettCheck" and Column "Id" someelem.value=result; // assign a new value to the input var event = new Event('change'); someelem.dispatchEvent(event); // signal to listeners (angularjs) that the value has changed }
Acting after Angular Page Has Fully Loaded
The script below can be added to your page and will call a function StartTheProcess after the data has been bound in Angular (data need not have been downloaded - but it is bound by AngularJS)
angular.element(function () { console.log('page loading completed'); startTheProcess(); });
You can then use AngularJS functions like $watch to find out when data is available or changed like this (this example was taken from a bank integration for EasyArr - Swedbank):
var initiated=false; function startTheProcess() { console.log('startTheProcess'); //debugger; var thescope=angular.element('#viewmodelWrapper').controller().$scope; if (!initiated){ initiated=true; thescope.$watch('ViewModelRoot.DataIsLoaded', function (newv, oldval, thescope) { console.log('startTheProcess WATCH DataIsLoaded '+newv); if (newv=="DataIsLoaded"){ thescope.ViewClient.CallServerAction('SwedbankPay','SCRIPTSCALLCheckIn',null); // handles the case when we called CheckIn too early } }); thescope.$watch('ViewModelRoot.FetchedScriptUrlForCheckin', function (newv, oldval, thescope) { console.log('startTheProcess WATCH FetchedScriptUrlForCheckin '+newv); if (newv && newv!=""){ DoCheckInScript(newv,thescope); } }); thescope.$watch('ViewModelRoot.FetchedScriptUrlForPaymentUI', function (newv, oldval, thescope) { console.log('startTheProcess WATCH FetchedScriptUrlForPaymentUI '+newv); if (newv && newv!=""){ DoPaymentUIScript(newv,thescope); } }); thescope.$watch('ViewModelRoot.ConsumerId', function (newv, oldval, thescope) { console.log('startTheProcess WATCH ConsumerId '+newv); if (newv && newv!=""){ DoPaymentOrderForThisConsumerProfile(newv,thescope); } }); } else{ console.log('startTheProcess - init skipped'); } thescope.ViewClient.CallServerAction('SwedbankPay','SCRIPTSCALLCheckIn',null) console.log('startTheProcess CheckIn'); }