@@ -177,6 +177,7 @@ private void DataBind(IDotvvmRequestContext context)
177177 head = null ;
178178
179179 var dataSourceBinding = GetDataSourceBinding ( ) ;
180+ var serverOnly = dataSourceBinding is not IValueBinding ;
180181 var dataSource = DataSource ;
181182
182183 var sortCommand = SortChanged ;
@@ -196,7 +197,7 @@ private void DataBind(IDotvvmRequestContext context)
196197 foreach ( var item in GetIEnumerableFromDataSource ( ) ! )
197198 {
198199 // create row
199- var placeholder = new DataItemContainer { DataItemIndex = index } ;
200+ var placeholder = new DataItemContainer { DataItemIndex = index , RenderItemBinding = ! serverOnly } ;
200201 placeholder . SetDataContextTypeFromDataSource ( dataSourceBinding ) ;
201202 placeholder . DataContext = item ;
202203 placeholder . SetValue ( Internal . PathFragmentProperty , GetPathFragmentExpression ( ) + "/[" + index + "]" ) ;
@@ -431,19 +432,22 @@ protected override void RenderContents(IHtmlWriter writer, IDotvvmRequestContext
431432 head ? . Render ( writer , context ) ;
432433
433434 // render body
434- var foreachBinding = TryGetKnockoutForeachExpression ( ) . NotNull ( "GridView does not support DataSource={resource: ...} at this moment." ) ;
435- if ( RenderOnServer )
435+ var foreachBinding = TryGetKnockoutForeachExpression ( ) ;
436+ if ( foreachBinding is { } )
436437 {
437- writer . AddKnockoutDataBind ( "dotvvm-SSR-foreach" , "{data:" + foreachBinding + "}" ) ;
438- }
439- else
440- {
441- writer . AddKnockoutForeachDataBind ( foreachBinding ) ;
438+ if ( RenderOnServer )
439+ {
440+ writer . AddKnockoutDataBind ( "dotvvm-SSR-foreach" , "{data:" + foreachBinding + "}" ) ;
441+ }
442+ else
443+ {
444+ writer . AddKnockoutForeachDataBind ( foreachBinding ) ;
445+ }
442446 }
443447 writer . RenderBeginTag ( "tbody" ) ;
444448
445449 // render contents
446- if ( RenderOnServer )
450+ if ( RenderOnServer || foreachBinding is null )
447451 {
448452 // render on server
449453 var index = 0 ;
@@ -498,16 +502,19 @@ protected override void RenderBeginTag(IHtmlWriter writer, IDotvvmRequestContext
498502 {
499503 if ( ! ShowHeaderWhenNoData )
500504 {
501- writer . WriteKnockoutDataBindComment ( "if" ,
502- GetForeachDataBindExpression ( ) . GetProperty < DataSourceLengthBinding > ( ) . Binding . CastTo < IValueBinding > ( ) . GetKnockoutBindingExpression ( this ) ) ;
505+ if ( GetForeachDataBindExpression ( ) . GetProperty < DataSourceLengthBinding > ( ) . Binding is IValueBinding conditionValueBinding )
506+ {
507+ writer . WriteKnockoutDataBindComment ( "if" , conditionValueBinding . GetKnockoutBindingExpression ( this ) ) ;
508+ }
503509 }
504510
505511 base . RenderBeginTag ( writer , context ) ;
506512 }
507513
508514 protected override void RenderControl ( IHtmlWriter writer , IDotvvmRequestContext context )
509515 {
510- if ( RenderOnServer && numberOfRows == 0 && ! ShowHeaderWhenNoData )
516+ var ssr = RenderOnServer || GetForeachDataBindExpression ( ) is not IValueBinding ;
517+ if ( ssr && numberOfRows == 0 && ! ShowHeaderWhenNoData )
511518 {
512519 emptyDataContainer ? . Render ( writer , context ) ;
513520 }
@@ -521,7 +528,7 @@ protected override void RenderEndTag(IHtmlWriter writer, IDotvvmRequestContext c
521528 {
522529 base . RenderEndTag ( writer , context ) ;
523530
524- if ( ! ShowHeaderWhenNoData )
531+ if ( ! ShowHeaderWhenNoData && GetForeachDataBindExpression ( ) is IValueBinding )
525532 {
526533 writer . WriteKnockoutDataBindEndComment ( ) ;
527534 }
@@ -531,15 +538,15 @@ protected override void RenderEndTag(IHtmlWriter writer, IDotvvmRequestContext c
531538
532539 protected override void AddAttributesToRender ( IHtmlWriter writer , IDotvvmRequestContext context )
533540 {
534- var itemType = ReflectionUtils . GetEnumerableType ( GetDataSourceBinding ( ) . ResultType ) ;
535- var userColumnMappingService = context . Services . GetRequiredService < UserColumnMappingCache > ( ) ;
536- var mapping = userColumnMappingService . GetMapping ( itemType ! ) ;
537- var mappingJson = JsonConvert . SerializeObject ( mapping ) ;
538-
539- var dataBinding =
540- ( GetDataSourceBinding ( ) as IValueBinding ?? throw new DotvvmControlException ( this , "GridView does not support DataSource={resource: ...} at this moment." ) )
541- . GetKnockoutBindingExpression ( this , unwrapped : true ) ;
542- writer . AddKnockoutDataBind ( "dotvvm-gridviewdataset" , $ "{{'mapping': { mappingJson } ,'dataSet': { dataBinding } }}" ) ;
541+ if ( GetBinding ( DataSourceProperty ) is IValueBinding dataBinding )
542+ {
543+ var itemType = ReflectionUtils . GetEnumerableType ( GetDataSourceBinding ( ) . ResultType ) ;
544+ var userColumnMappingService = context . Services . GetRequiredService < UserColumnMappingCache > ( ) ;
545+ var mapping = userColumnMappingService . GetMapping ( itemType ! ) ;
546+ var mappingJson = JsonConvert . SerializeObject ( mapping ) ;
547+
548+ writer . AddKnockoutDataBind ( "dotvvm-gridviewdataset" , $ "{{'mapping': { mappingJson } ,'dataSet': { dataBinding . GetKnockoutBindingExpression ( this , unwrapped : true ) } }}" ) ;
549+ }
543550 base . AddAttributesToRender ( writer , context ) ;
544551 }
545552
0 commit comments