Skip to content

Commit

Permalink
datasets: fix generating client-side reload expression
Browse files Browse the repository at this point in the history
  • Loading branch information
exyi committed Oct 7, 2023
1 parent 015a691 commit 62b7fe7
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,7 @@ private void AddDataSetOptionsTranslations()
{
// GridViewDataSetBindingProvider
AddMethodTranslator(typeof(GridViewDataSetBindingProvider), "DataSetClientSideLoad", new GenericMethodCompiler(args =>
new JsIdentifierExpression("dotvvm").Member("dataSet").Member("loadDataSet").Invoke(args[1], args[2])));
new JsIdentifierExpression("dotvvm").Member("dataSet").Member("loadDataSet").Invoke(args[1].WithAnnotation(ShouldBeObservableAnnotation.Instance), new JsSymbolicParameter(JavascriptTranslator.KnockoutContextParameter).Member("$gridViewDataSetHelper").Member("loadDataSet")).WithAnnotation(new ResultIsPromiseAnnotation(e => e))));

// PagingOptions
AddMethodTranslator(() => default(PagingOptions)!.GoToFirstPage(),new GenericMethodCompiler(args =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ public void VisitMemberAccessExpression(JsMemberAccessExpression memberAccessExp
{
EmitComment(memberAccessExpression.CommentBefore);
if (!memberAccessExpression.MemberNameToken.IsValidName())
new JsIndexerExpression(memberAccessExpression.Target.Clone(), new JsLiteral(memberAccessExpression.MemberNameToken))
new JsIndexerExpression(memberAccessExpression.Target.Clone(), new JsLiteral(memberAccessExpression.MemberName))
.AcceptVisitor(this);
else
{
Expand Down
36 changes: 7 additions & 29 deletions src/Framework/Framework/Controls/GridViewDataSetBindingProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ private ICommandBinding CreateCommandBinding<TDataSetInterface>(GridViewDataSetC
else if (commandType == GridViewDataSetCommandType.StaticCommand)
{
// on the client, wrap the call into client-side loading procedure
var expression = WrapInDataSetClientLoad(dataSetParam, body);
body.Add(CallClientSideLoad(dataSetParam));
Expression expression = Expression.Block(body);
if (transformExpression != null)
{
expression = transformExpression(expression);
Expand All @@ -165,43 +166,20 @@ private ICommandBinding CreateCommandBinding<TDataSetInterface>(GridViewDataSetC
}

/// <summary>
/// Wraps the block expression { dataSet.XXXOptions.Method(); dataSet.RequestRefresh(); }
/// as loaderFunction => { ...; return GridViewDataSetBindingProvider.DataSetClientSideLoad(dataSet, loaderFunction); });
/// Invoked the client-side loadDataSet function with the loader from $gridViewDataSetHelper
/// </summary>
private static Expression WrapInDataSetClientLoad(Expression dataSetParam, List<Expression> body)
private static Expression CallClientSideLoad(Expression dataSetParam)
{
// get options and data set item type
var dataSetType = dataSetParam.Type;
var filteringOptionsConcreteType = GetOptionsConcreteType<IFilterableGridViewDataSet<IFilteringOptions>>(dataSetType, out _);
var sortingOptionsConcreteType = GetOptionsConcreteType<ISortableGridViewDataSet<ISortingOptions>>(dataSetType, out _);
var pagingOptionsConcreteType = GetOptionsConcreteType<IPageableGridViewDataSet<IPagingOptions>>(dataSetType, out _);
var dataSetItemType = dataSetType.GetInterfaces()
.Single(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IBaseGridViewDataSet<>))
.GetGenericArguments()[0];

// resolve generic method and its parameter
var method = typeof(GridViewDataSetBindingProvider).GetMethod(nameof(DataSetClientSideLoad))!
.MakeGenericMethod(dataSetType, dataSetItemType, filteringOptionsConcreteType, sortingOptionsConcreteType, pagingOptionsConcreteType);
var loaderFunctionParam = Expression.Parameter(method.GetParameters().Single(p => p.Name == "loaderFunction").ParameterType, "loaderFn");

// call static method DataSetClientLoad
var callClientLoad = Expression.Call(method, dataSetParam, loaderFunctionParam);
return Expression.Lambda(Expression.Block(body.Concat(new [] { callClientLoad })), loaderFunctionParam);
var method = typeof(GridViewDataSetBindingProvider).GetMethod(nameof(DataSetClientSideLoad))!;
return Expression.Call(method, dataSetParam);
}

/// <summary>
/// A sentinel method which is translated to load the GridViewDataSet on the client side using the Load delegate.
/// Do not call this method on the server.
/// </summary>
public static Task DataSetClientSideLoad<TGridViewDataSet, T, TFilteringOptions, TSortingOptions, TPagingOptions>
(
TGridViewDataSet dataSet,
Func<GridViewDataSetOptions<TFilteringOptions, TSortingOptions, TPagingOptions>, Task<GridViewDataSetResult<T, TFilteringOptions, TSortingOptions, TPagingOptions>>> loaderFunction
)
where TGridViewDataSet : IBaseGridViewDataSet<T>, IFilterableGridViewDataSet<TFilteringOptions>, ISortableGridViewDataSet<TSortingOptions>, IPageableGridViewDataSet<TPagingOptions>
where TFilteringOptions : IFilteringOptions
where TSortingOptions : ISortingOptions
where TPagingOptions : IPagingOptions
public static Task DataSetClientSideLoad(IBaseGridViewDataSet dataSet)
{
throw new InvalidOperationException("This method cannot be called on the server!");
}
Expand Down
5 changes: 3 additions & 2 deletions src/Tests/ViewModel/GridViewDataSetTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ public void GridViewDataSet_DataPagerCommands_StaticCommand()
var commands = commandProvider.GetDataPagerCommands(dataContextStack, GridViewDataSetCommandType.StaticCommand);

var goToFirstPage = CompileBinding(commands.GoToFirstPage);
Console.WriteLine(goToFirstPage);
XAssert.Equal("dotvvm.applyPostbackHandlers(async (options)=>{let vm=options.viewModel;dotvvm.dataSet.translations.PagingOptions.goToFirstPage(vm.PagingOptions);return await dotvvm.dataSet.loadDataSet(vm,options.knockoutContext.$gridViewDataSetHelper.loadDataSet);},this)", goToFirstPage);
}

private string CompileBinding(ICommandBinding staticCommand)
Expand All @@ -134,8 +136,7 @@ private string CompileBinding(ICommandBinding staticCommand)
new Literal(),
new PostbackScriptOptions(
allowPostbackHandlers: false,
returnValue: null,
commandArgs: CodeParameterAssignment.FromLiteral("commandArguments")
returnValue: null
));
}

Expand Down

0 comments on commit 62b7fe7

Please sign in to comment.