@@ -16,7 +16,8 @@ public class EditForm : ComponentBase
16
16
{
17
17
private readonly Func < Task > _handleSubmitDelegate ; // Cache to avoid per-render allocations
18
18
19
- private EditContext ? _fixedEditContext ;
19
+ private EditContext ? _editContext ;
20
+ private bool _hasSetEditContextExplicitly ;
20
21
21
22
/// <summary>
22
23
/// Constructs an instance of <see cref="EditForm"/>.
@@ -36,7 +37,16 @@ public EditForm()
36
37
/// also supply <see cref="Model"/>, since the model value will be taken
37
38
/// from the <see cref="EditContext.Model"/> property.
38
39
/// </summary>
39
- [ Parameter ] public EditContext ? EditContext { get ; set ; }
40
+ [ Parameter ]
41
+ public EditContext ? EditContext
42
+ {
43
+ get => _editContext ;
44
+ set
45
+ {
46
+ _editContext = value ;
47
+ _hasSetEditContextExplicitly = value != null ;
48
+ }
49
+ }
40
50
41
51
/// <summary>
42
52
/// Specifies the top-level model object for the form. An edit context will
@@ -73,11 +83,16 @@ public EditForm()
73
83
/// <inheritdoc />
74
84
protected override void OnParametersSet ( )
75
85
{
76
- if ( ( EditContext == null ) == ( Model == null ) )
86
+ if ( _hasSetEditContextExplicitly && Model != null )
77
87
{
78
88
throw new InvalidOperationException ( $ "{ nameof ( EditForm ) } requires a { nameof ( Model ) } " +
79
89
$ "parameter, or an { nameof ( EditContext ) } parameter, but not both.") ;
80
90
}
91
+ else if ( ! _hasSetEditContextExplicitly && Model == null )
92
+ {
93
+ throw new InvalidOperationException ( $ "{ nameof ( EditForm ) } requires either a { nameof ( Model ) } " +
94
+ $ "parameter, or an { nameof ( EditContext ) } parameter, please provide one of these.") ;
95
+ }
81
96
82
97
// If you're using OnSubmit, it becomes your responsibility to trigger validation manually
83
98
// (e.g., so you can display a "pending" state in the UI). In that case you don't want the
@@ -89,31 +104,31 @@ protected override void OnParametersSet()
89
104
$ "{ nameof ( EditForm ) } , do not also supply { nameof ( OnValidSubmit ) } or { nameof ( OnInvalidSubmit ) } .") ;
90
105
}
91
106
92
- // Update _fixedEditContext if we don't have one yet, or if they are supplying a
107
+ // Update _editContext if we don't have one yet, or if they are supplying a
93
108
// potentially new EditContext, or if they are supplying a different Model
94
- if ( _fixedEditContext == null || EditContext != null || Model != _fixedEditContext . Model )
109
+ if ( Model != null && Model != _editContext ? . Model )
95
110
{
96
- _fixedEditContext = EditContext ?? new EditContext ( Model ! ) ;
111
+ _editContext = new EditContext ( Model ! ) ;
97
112
}
98
113
}
99
114
100
115
/// <inheritdoc />
101
116
protected override void BuildRenderTree ( RenderTreeBuilder builder )
102
117
{
103
- Debug . Assert ( _fixedEditContext != null ) ;
118
+ Debug . Assert ( _editContext != null ) ;
104
119
105
- // If _fixedEditContext changes, tear down and recreate all descendants.
120
+ // If _editContext changes, tear down and recreate all descendants.
106
121
// This is so we can safely use the IsFixed optimization on CascadingValue,
107
- // optimizing for the common case where _fixedEditContext never changes.
108
- builder . OpenRegion ( _fixedEditContext . GetHashCode ( ) ) ;
122
+ // optimizing for the common case where _editContext never changes.
123
+ builder . OpenRegion ( _editContext . GetHashCode ( ) ) ;
109
124
110
125
builder . OpenElement ( 0 , "form" ) ;
111
126
builder . AddMultipleAttributes ( 1 , AdditionalAttributes ) ;
112
127
builder . AddAttribute ( 2 , "onsubmit" , _handleSubmitDelegate ) ;
113
128
builder . OpenComponent < CascadingValue < EditContext > > ( 3 ) ;
114
129
builder . AddAttribute ( 4 , "IsFixed" , true ) ;
115
- builder . AddAttribute ( 5 , "Value" , _fixedEditContext ) ;
116
- builder . AddAttribute ( 6 , "ChildContent" , ChildContent ? . Invoke ( _fixedEditContext ) ) ;
130
+ builder . AddAttribute ( 5 , "Value" , _editContext ) ;
131
+ builder . AddAttribute ( 6 , "ChildContent" , ChildContent ? . Invoke ( _editContext ) ) ;
117
132
builder . CloseComponent ( ) ;
118
133
builder . CloseElement ( ) ;
119
134
@@ -122,26 +137,26 @@ protected override void BuildRenderTree(RenderTreeBuilder builder)
122
137
123
138
private async Task HandleSubmitAsync ( )
124
139
{
125
- Debug . Assert ( _fixedEditContext != null ) ;
140
+ Debug . Assert ( _editContext != null ) ;
126
141
127
142
if ( OnSubmit . HasDelegate )
128
143
{
129
144
// When using OnSubmit, the developer takes control of the validation lifecycle
130
- await OnSubmit . InvokeAsync ( _fixedEditContext ) ;
145
+ await OnSubmit . InvokeAsync ( _editContext ) ;
131
146
}
132
147
else
133
148
{
134
149
// Otherwise, the system implicitly runs validation on form submission
135
- var isValid = _fixedEditContext . Validate ( ) ; // This will likely become ValidateAsync later
150
+ var isValid = _editContext . Validate ( ) ; // This will likely become ValidateAsync later
136
151
137
152
if ( isValid && OnValidSubmit . HasDelegate )
138
153
{
139
- await OnValidSubmit . InvokeAsync ( _fixedEditContext ) ;
154
+ await OnValidSubmit . InvokeAsync ( _editContext ) ;
140
155
}
141
156
142
157
if ( ! isValid && OnInvalidSubmit . HasDelegate )
143
158
{
144
- await OnInvalidSubmit . InvokeAsync ( _fixedEditContext ) ;
159
+ await OnInvalidSubmit . InvokeAsync ( _editContext ) ;
145
160
}
146
161
}
147
162
}
0 commit comments