Closed jasononeil closed 8 years ago
This may be a solution to #23
Let me have trial on this concept:
// psuedo-code
class UpdatePasswordAction implements UFClientAction
{
@inject public var asyncApi:MyAsyncApi;
public function execute(ctx, data)
{
ui.showLoading(); // add a css spin wheel, disable the textbox etc
asyncApi.updatePassword(data.password).handle(function()
{
ui.hideLoading(); // remove the stuff
});
}
}
is it that simple? That looks very nice to me!
One more thing, since this is purely client JS stuff. I anticipate a lot of DOM manipulation or HTML templating. I think adding some helper functionality would help, e.g:
// fetch (and cache) a template file from server and execute it with data
// then it can be used in: dom.innerHTML = resultHtml;
function executeTemplate(filePath:String, data:Dynamic)
i think that .addClientAction should be implemented also in PartialResult
Some other ideas . Passing params to action In partialresult the action si called after rendering of partial. calling an action first of rendering?
@kevinresol you have the right idea, glad you like it. I agree a bunch of helpers would be necessary. I recently cleaned up ViewResult, and it shouldn't be too hard to add a renderPartial(file,data):String
helper now.
@francescoagati .addClientAction()
would work with any ActionResult that returns HTML (so ViewResult, PartialViewResult, ContentResult etc). I'm not sure I understood the other ideas you were writing - could you explain a bit more?
One question to ask, is data
type safe?
public function execute(ctx:HttpContext, ?data:Dynamic):Void
// or
public function execute(ctx:HttpContext, ?data:T):Void
Because it can be called via JS, or the version on the client may be different to the version on the server, we can't really guarantee type safety. So we can have no type safety or some type safety, but not fully guaranteed type safety.
Another option could be to use a macro to slot in a var data = Std.instance( data, T )
line, so the data is either correct, or null.
Also I'm thinking whatever T
is should be JSON compatible, so it's easy to transport from server->client. We could also use Haxe serialization, but it makes it harder to interact with non-haxe code then.
Client Action can be generic and passing parameters is necessary sometimes. For example pass a reference of node element.
I prefer a type-safe one. For pure JS call, I think we can't do much checking there, for example T
could be a structrual typedef which can't be checked at runtime.
what if UFClientAction
declares a checkInput(data:T):Bool
interface then use macro to force call it at the beginning of execute
? so the user just implement their own method. They can choose to simply return true
if they don't want to check it.
cool ! that reminds me the signal/command used in mmvc ( based on robotlegs ) https://github.com/massiveinteractive/mmvc which i like a lot. i agree with the fact we should be able to interact with the action chains without having to rely on the dom. Also , you should have a look on how signal/command are called and executed in mmvc .I think this is a good example of what you are thinking of.
This is a fairly major idea, though it would be fairly easy to implement. I'd like to hear if anyone has feedback first before I start coding though :) I've tried to explain it in detail, with examples.
Background:
Ufront-Client is great at emulating a server-side HTTP request / response cycle entirely client side, in Javascript. But there are some actions that are just plain JS, and don't need a full page load, their own URL, or their own ActionResult / HttpResult.
I'm proposing we build a
UFClientAction
type to work for these situations.Examples:
Definition of UFClientAction
Pseudo-code
Triggering actions from the client
From your Haxe code:
Or some arbitrary JS:
We could possibly also have some tie in to HTML events:
How actions are added from a regular request (client or server)
We create a helper, like this:
Similar to
CallJavascriptResult
, this would add a snippet to the response:Adding actions to your ClientJsApplication
Similar to how every
UFApi
is automatically imported into your app and available for injection, I propose we do:How actions are executed
When the app goes to execute an action:
var action = clientApp.getValue( actionCls )
.action.execute( clientApp.currentContext, data );
PartialViewResult.replacePartial("notifications", "notifications.html", { list:newNotifications });
Advantages of this approach
Disadvantages