Geeksltd / Olive

Olive framework, for more productive cross platform .NET solutions. It's available under the GPL v3 license. See License.md for more information.
https://geeksltd.github.io/Olive
Other
44 stars 44 forks source link

Fix : Start-up scripts be rendered more than once in Ajax-Post request #246

Closed tohfe closed 5 years ago

PaymonK commented 5 years ago

Can you explain the reason for this?

tohfe commented 5 years ago

I explain a real example from Tasks app : In the notification page, there is a button titled "Dismiss" . The M# code for this button is : ButtonColumn("Dismiss") .ValidateAntiForgeryToken(false) .OnClick(x => { x.CSharp("await item.ChangeCheckedState(true);"); x.Reload(); } );

The generated codes for onclick event is :

    [HttpPost("NotificationsList/Dismiss")]
    public async Task<ActionResult> Dismiss(vm.NotificationsList info, [Bind(Prefix="list.item")] Notification item)
    {
        await item.ChangeCheckedState(true);

        await TryUpdateModelAsync(info);
        return View(info);
    }

It should run a Javascript code after returning from server, so I add a line to load a javascript module : ButtonColumn("Dismiss") .ValidateAntiForgeryToken(false) .OnClick(x => { x.CSharp("await item.ChangeCheckedState(true);"); x.LoadJavascriptModule("scripts/components/masterpage.js", absoluteUrl: true); x.Reload(); } ); and the Generated code will be :

    [HttpPost("NotificationsList/Dismiss")]
    public async Task<ActionResult> Dismiss(vm.NotificationsList info, [Bind(Prefix="list.item")] Notification item)
    {
        using (var scope = Database.CreateTransactionScope())
        {
            await item.ChangeCheckedState(true);

            **JavaScript(JavascriptModule.Absolute("scripts/components/masterpage.js"), "run()");**

            await TryUpdateModelAsync(info);

            scope.Complete();
            return View(info);
        }

        return JsonActions(info);
    }

Clicking on "Dismiss" button will create a "Ajax Post" action, and when the server side codes are executed. the rendered response will contains too many "Startup Script" inputs that will cause the JS code executes more than one time. I check the Olive codes and realized that if the request is "Ajax post" it will render "Startup Script" for every module and this page uses more than one module.

I had this problem when I was implementing "Comments" modules. In that time I spent too many hours to fix this problem by changing "Tasks app" codes (not Olive codes). I did it but my solution was temporary. For Comments module implementation I removed extra "Startup script" inputs in client side and...

By merging this pull request, The redundant "Startup scripts" will not added to response

Although I can do this by changing the " x.Reload();" to "x.RefreshPage();", but I wanted to solve this problem too