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)
|
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)
|
public override void WriteCSharpExpression(CodeRenderingContext context, CSharpExpressionIntermediateNode node)
|
||||||
|
|
|
||||||
|
|
@ -236,18 +236,53 @@ namespace Microsoft.Blazor.Build.Test
|
||||||
{
|
{
|
||||||
// Arrange/Act
|
// Arrange/Act
|
||||||
var component = CompileToComponent(
|
var component = CompileToComponent(
|
||||||
"<elem attr=@MyHandleEvent />"
|
@"<elem attr=@MyHandleEvent />
|
||||||
+ @"@functions {
|
@functions {
|
||||||
void MyHandleEvent(Microsoft.Blazor.RenderTree.UIEventArgs eventArgs) {}
|
public bool HandlerWasCalled { get; set; } = false;
|
||||||
}");
|
|
||||||
|
void MyHandleEvent(Microsoft.Blazor.RenderTree.UIEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
HandlerWasCalled = true;
|
||||||
|
}
|
||||||
|
}");
|
||||||
|
var handlerWasCalledProperty = component.GetType().GetProperty("HandlerWasCalled");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Collection(GetRenderTree(component),
|
Assert.False((bool)handlerWasCalledProperty.GetValue(component));
|
||||||
|
Assert.Collection(GetRenderTree(component).Where(NotWhitespace),
|
||||||
node => AssertNode.Element(node, "elem", 1),
|
node => AssertNode.Element(node, "elem", 1),
|
||||||
node =>
|
node =>
|
||||||
{
|
{
|
||||||
Assert.Equal(RenderTreeNodeType.Attribute, node.NodeType);
|
Assert.Equal(RenderTreeNodeType.Attribute, node.NodeType);
|
||||||
Assert.NotNull(node.AttributeEventHandlerValue);
|
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>
|
<h1>Counter</h1>
|
||||||
<p>Current count: @currentCount</p>
|
<p>Current count: @currentCount</p>
|
||||||
<button onclick=@OnButtonClicked>Click me</button>
|
<button onclick=@{ currentCount++; }>Click me</button>
|
||||||
|
|
||||||
@functions {
|
@functions {
|
||||||
int currentCount = 0;
|
int currentCount = 0;
|
||||||
|
|
||||||
void OnButtonClicked(Microsoft.Blazor.RenderTree.UIEventArgs eventArgs)
|
|
||||||
{
|
|
||||||
currentCount++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue