AXForum  
Вернуться   AXForum > Microsoft Dynamics NAV > NAV: Blogs
NAV
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 19.11.2019, 22:12   #1  
Blog bot is offline
Blog bot
Участник
 
25,475 / 846 (79) +++++++
Регистрация: 28.10.2006
Navigate Into Success: Microsoft.Dynamics.NAV.InvokeExtensibilityMethod
Источник: http://vjeko.com/microsoft-dynamics-...ibilitymethod/
==============

Now that you are done through this mouthful of the title,you may recognize that it’s the method you invoke when you want to run a controladd-in trigger in AL from JavaScript.

There is nothing new about this method itself, it’s justthat most people aren’t aware of full power of this method, and they are usingthis method in a very inefficient way. In this blog, I want to show you whatthis method can do for you that you may have not been aware of. And I hope Iget you to change your habits.

The syntax is this:

Microsoft.Dynamics.NAV.InvokeExtensibilityMethod(name, args[, skipIfBusy[, callback]]);It takes at minimum two arguments, and this is what mostpeople invoke it. Obviously, name is the name of the event as declaredin the controladdin object that youalso must implement as a trigger inside the usercontrolin the page that uses it. Also, args is the array of arguments you wantto pass to AL.

Imagine this is how you declare your event:

event SayHello(FirstName: Text; LastName: Text);Then from JavaScript you would invoke it like this:

Microsoft.Dynamics.NAV.InvokeExtensibilityMethod("SayHello", ["John", "Doe"]);So far, very simple, obvious, and easy. But here we get to the biggest mistake most people do when invoking the Microsoft.Dynamics.NAV.InvokeExtensibilityMethod method. They invoke it directly. The reason why it’s a mistake is because most often you’ll want to synchronize the invocations between JavaScript and AL as much as you can, and this method – as anything in JavaScript that invokes stuff outside JavaScript – is asynchronous. If you have this:

Microsoft.Dynamics.NAV.InvokeExtensibilityMethod("SayHello", ["John", "Doe"]);alert("You see me immediately");… you will see the “You see me immediately” message beforeAL even gets a chance to start executing.

Yes, you can take advantage of more arguments here to makeit behave differently. So, let’s take a look at the remaining two arguments.

The skipIfBusy argument tells the control add-inJavaScript runtime to not even invoke your event in AL if the NST session iscurrently busy doing something else. If you omit it, the skipIfBusy parameterdefaults to false so it means your AL event will be raised, and if AL isalready busy, it will be raised as soon as AL stops being busy.

The callback argument, though, is where cool stuffhappens. This arguments is of function type (you can imply as much from itsname), and it is invoked as soon as AL has finished doing whatever you justmade it busy with. So, if you want some JavaScript code to happen after the SayHelloevent completes its work, you can do it like this:

Microsoft.Dynamics.NAV.InvokeExtensibilityMethod( "SayHello", ["John", "Doe"], false, function() { alert("You see me after SayHello finished running in AL"); });However, that’s not really the most beautiful way of writingJavaScript. That’s how you would write it in late 1990’s, we are now nearly aquarter century ahead. Let’s write some at least tiny little bit less outdatedJavaScript, and let’s introduce Promises.Promises are objects which allow you to synchronize asynchronous calls in asyntactically less offensive way than callbacks.

Let’s take a look at why promises are superior to callbacks.

Imagine you want to structure your code nicely, and you don’twant to just call your extensibility methods out of a blue, so you decide towrap your call into a function, like this:

function sayHello(first, last, callback) { Microsoft.Dynamics.NAV.InvokeExtensibilityMethod( "SayHello", [first, last], false, callback); } // Invoking the function sayHello("John", "Doe", function() { alert("You see me after SayHello finished running in AL"); });The syntax of the sayHello invocation is not really that easy to follow. However, we could translate the entire example to promises:

function sayHello(first, last) { return new Promise(resolve => Microsoft.Dynamics.NAV.InvokeExtensibilityMethod( "SayHello", [first, last], false, resolve));}// Invoking the functionsayHello("John", "Doe") .then(() => alert("You see me after SayHello finished running in AL"));… and suddenly it becomes more readable. (Okay, a part of itbeing more readable is that I used arrowfunctions, but that’s because they are both supported at the same language levelof JavaScript, and if your browser supports Promises, it will support arrowfunctions too, and if it doesn’t support Promises, it won’t support arrowfunctions either).

Apart from this readability benefit, there is another, farbigger benefit of wrapping yourMicrosoft.Dynamics.NAV.InvokeExtensibilityMethod invocations into promise-returningwrapper functions: it’s the fact that all promises are awaitable inJavaScript.

In newer versions of JavaScript (EcmaScript 2017 and newer)there is a concept of asyncfunctions. Async functions perform some asynchronous work, and you can awaiton them to make your code look and behave as if it were synchronous.

For example, if you have a function declared as this:

async function somethingAsync() { // Do some asynchronous work}… then you can invoke it like this:

await somethingAsync();alert("This won’t execute before somethingAsync completes its async work");Cool thing about async/await is that it’s nothing more than syntactic sugar for Promises.Every async function implicitly returns a Promise, and you can invoke it eitherwith await syntax, or with .then() syntax. Cosenquently, if a functionexplicitly returns a Promise, you can awaiton it as if it were declared as async.

In short, in our earlier example, we could easily do this:

function sayHello(first, last) { return new Promise(resolve => Microsoft.Dynamics.NAV.InvokeExtensibilityMethod( "SayHello", [first, last], false, resolve));}// Invoking the functionawait sayHello("John", "Doe");alert("You see me after SayHello finished running in AL");… and it would have exactly the same meaning as the earlierexample, except that this time it’s far more readable.

At this stage, our sayHellofunction is a handy asynchronous wrapper around Microsoft.Dynamics.NAV.InvokeExtensibilityMethodmethod invocation, but we can do better than that. Instead of having to writewrappers for every single event declared in your controladdinobject, you could write something like this:

function getALEventHandler(eventName, skipIfBusy) { return (…args) => new Promise(resolve => Microsoft.Dynamics.NAV.InvokeExtensibilityMethod( eventName, args, skipIfBusy, resolve));}When you have that, you can use it like this:

// Obtain a reference to an asynchronous event invocation wrappervar sayHello = getALEventHandler("SayHello", false);// … and then use it as an asynchronous functionawait sayHello("John", "Doe");alert("You see me after SayHello finished running in AL");Cool, isn’t it? You now not only never have to write thatwordy Microsoft.Dynamics.NAV.InvokeExtensibilityMethodever again (and risk making typos), you also have it fully synchronizable usingthe await syntax. But we can get evencooler – way cooler – than that. Hold my beer.

You know already that event invocations in AL are void,or that they cannot ever return a value. Your JavaScript cannot invoke AL andhave AL return a value to it, that’s just not how AL/JavaScript integrationworks. At the heart it’s because it’s all asynchronous, but at the end of it,it’s just because Microsoft never cared enough to make it fully synchronized throughan abstraction layer that could make it possible. Now that we’ve got it to an awaitablestage, let’s take it to another level by allowing AL to actually return valuesto your JavaScript wrappers.

Imagine that you declare this event in your controlladdin:

event GetCustomer(No: Code[10]);You pass a customer number to it, and you want it to return a JSON object containing your customer record information by its primary key. Ideally, you’ll want to invoke it like this:

var cust = await getCustomer("10000");Of course, that won’t work, because your GetCustomer trigger in AL – once you implement it in a page – cannot return values. You’d have to have a method declared in your controladdin object and then implement that method in the global scope in JavaScript, where you can pass the result of this operation, something you’d declare like this:

procedure GetCustomerResult(Cust: JsonObject);However, implementing it as a separate function in yourJavaScript would require some acrobatics to allow you to retain your await getCustomer() syntax. But this isonly true if you take the traditional approach of implementing methods asglobal-scope-level functions in one of your scripts. In JavaScript, you canimplement methods on the fly, so let’s do it.

Let’s start with the statement that the GetCustomerResultfunction should be available in JavaScript only during the invocation of GetResultevent in AL, and invoking it outside of such invocation would be a bug, andshould not be allowed. When you do it like this, then you can write your codein such a way that you create this function in JavaScript just before youinvoke the AL event, and you delete this function immediately when AL returnsthe result, something like this:

function getALEventHandler(eventName, skipIfBusy) { return (...args) => new Promise(resolve => { var result; var eventResult = `${eventName}Result`; window[eventResult] = alresult => { result = alresult; delete window[eventResult]; }; Microsoft.Dynamics.NAV.InvokeExtensibilityMethod( eventName, args, skipIfBusy, () => resolve(result)); });}You can then do something like this:

// Obtain a reference to an asynchronous event invocation wrappervar getCustomer = getALEventHandler("GetCustomer", false);// … and then use it as an asynchronous functionvar cust = await getCustomer("10000");alert(Your customer record is ${JSON.stringify(cust)});How cool is this?

There is an even further level of awesomeness you can add toyour event invocations, and it has to do with the skipIfBusy argument,but that’s a topic for a future blog post, I think you have enough to chew onfor now. And I know that at this stage, invoking Microsoft.Dynamics.NAV.InvokeExtensibilityMethoddirectly, instead of through a pattern such as this, seems very stone age.

Read this post at its original location at http://vjeko.com/microsoft-dynamics-...ibilitymethod/, or visit the original blog at http://vjeko.com. 5e33c5f6cb90c441bd1f23d5b9eeca34The post Microsoft.Dynamics.NAV.InvokeExtensibilityMethod appeared first on Vjeko.com.




Источник: http://vjeko.com/microsoft-dynamics-...ibilitymethod/
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
crminthefield: Podcast and Overview: Microsoft Dynamics CRM 2011 Update Rollup 15 Blog bot Dynamics CRM: Blogs 1 10.02.2016 10:26
Navigate Into Success: Drag and Drop File Upload for Microsoft Dynamics NAV 2013 R2 Blog bot Dynamics CRM: Blogs 0 12.03.2014 17:51
NAV Team: Upgrade Toolkit for Upgrading Data from Microsoft Dynamics NAV 2009 R2 and Microsoft Dynamics NAV 2009 SP1 to Microsoft Dynamics NAV 2013 R2 Blog bot Dynamics CRM: Blogs 0 22.11.2013 20:00
crminthefield: Podcast and Overview: Microsoft Dynamics CRM 2011 Update Rollup 12 Blog bot Dynamics CRM: Blogs 0 30.01.2013 01:11
NAV Team: New Training Titles Released for Microsoft Dynamics NAV 2009 SP1 Blog bot Dynamics CRM: Blogs 0 23.03.2010 17:40
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 00:14.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.