In RazorCompiler, support attributes whose values are C# code blocks (treated as event handlers)
This commit is contained in:
parent
5949045319
commit
7cd5228b7f
|
|
@ -76,7 +76,17 @@ namespace Microsoft.Blazor.Build.Core.RazorCompilation.Engine
|
|||
|
||||
public override void WriteCSharpCodeAttributeValue(CodeRenderingContext context, CSharpCodeAttributeValueIntermediateNode node)
|
||||
{
|
||||
throw new System.NotImplementedException(nameof(WriteCSharpCodeAttributeValue));
|
||||
if (_currentAttributeValues == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Invoked {nameof(WriteCSharpCodeAttributeValue)} while {nameof(_currentAttributeValues)} was null.");
|
||||
}
|
||||
|
||||
// For attributes like "onsomeevent=@{ /* some C# code */ }", we treat it as if you
|
||||
// wrote "onsomeevent=@(_ => { /* some C# code */ })" because then it works as an
|
||||
// event handler and is a reasonable syntax for that.
|
||||
var innerCSharp = (IntermediateToken)node.Children.Single();
|
||||
innerCSharp.Content = $"_ => {{ {innerCSharp.Content} }}";
|
||||
_currentAttributeValues.Add(innerCSharp);
|
||||
}
|
||||
|
||||
public override void WriteCSharpExpression(CodeRenderingContext context, CSharpExpressionIntermediateNode node)
|
||||
|
|
|
|||
|
|
@ -236,18 +236,53 @@ namespace Microsoft.Blazor.Build.Test
|
|||
{
|
||||
// Arrange/Act
|
||||
var component = CompileToComponent(
|
||||
"<elem attr=@MyHandleEvent />"
|
||||
+ @"@functions {
|
||||
void MyHandleEvent(Microsoft.Blazor.RenderTree.UIEventArgs eventArgs) {}
|
||||
}");
|
||||
@"<elem attr=@MyHandleEvent />
|
||||
@functions {
|
||||
public bool HandlerWasCalled { get; set; } = false;
|
||||
|
||||
void MyHandleEvent(Microsoft.Blazor.RenderTree.UIEventArgs eventArgs)
|
||||
{
|
||||
HandlerWasCalled = true;
|
||||
}
|
||||
}");
|
||||
var handlerWasCalledProperty = component.GetType().GetProperty("HandlerWasCalled");
|
||||
|
||||
// Assert
|
||||
Assert.Collection(GetRenderTree(component),
|
||||
Assert.False((bool)handlerWasCalledProperty.GetValue(component));
|
||||
Assert.Collection(GetRenderTree(component).Where(NotWhitespace),
|
||||
node => AssertNode.Element(node, "elem", 1),
|
||||
node =>
|
||||
{
|
||||
Assert.Equal(RenderTreeNodeType.Attribute, node.NodeType);
|
||||
Assert.NotNull(node.AttributeEventHandlerValue);
|
||||
|
||||
node.AttributeEventHandlerValue(null);
|
||||
Assert.True((bool)handlerWasCalledProperty.GetValue(component));
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SupportsAttributesWithCSharpCodeBlockValues()
|
||||
{
|
||||
// Arrange/Act
|
||||
var component = CompileToComponent(
|
||||
@"<elem attr=@{ DidInvokeCode = true; } />
|
||||
@functions {
|
||||
public bool DidInvokeCode { get; set; } = false;
|
||||
}");
|
||||
var didInvokeCodeProperty = component.GetType().GetProperty("DidInvokeCode");
|
||||
|
||||
// Assert
|
||||
Assert.False((bool)didInvokeCodeProperty.GetValue(component));
|
||||
Assert.Collection(GetRenderTree(component).Where(NotWhitespace),
|
||||
node => AssertNode.Element(node, "elem", 1),
|
||||
node =>
|
||||
{
|
||||
Assert.Equal(RenderTreeNodeType.Attribute, node.NodeType);
|
||||
Assert.NotNull(node.AttributeEventHandlerValue);
|
||||
|
||||
node.AttributeEventHandlerValue(null);
|
||||
Assert.True((bool)didInvokeCodeProperty.GetValue(component));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,7 @@
|
|||
<h1>Counter</h1>
|
||||
<p>Current count: @currentCount</p>
|
||||
<button onclick=@OnButtonClicked>Click me</button>
|
||||
<button onclick=@{ currentCount++; }>Click me</button>
|
||||
|
||||
@functions {
|
||||
int currentCount = 0;
|
||||
|
||||
void OnButtonClicked(Microsoft.Blazor.RenderTree.UIEventArgs eventArgs)
|
||||
{
|
||||
currentCount++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue