(0);
+ newTree2.AddAttribute(1, nameof(HandlePropertiesChangedComponent.IntProperty), 456);
+ newTree2.CloseElement();
+
+ // Act/Assert 0: Initial render
+ var batch0 = GetRenderedBatch(new RenderTreeBuilder(renderer), oldTree);
+ var diffForChildComponent0 = batch0.UpdatedComponents.Array[1];
+ var childComponentNode = batch0.UpdatedComponents.Array[0].CurrentState.Array[0];
+ var childComponentInstance = (HandlePropertiesChangedComponent)childComponentNode.Component;
+ Assert.Equal(1, childComponentInstance.NotificationsCount);
+ Assert.Collection(diffForChildComponent0.CurrentState,
+ node => AssertNode.Text(node, "Notifications: 1", 0));
+
+ // Act/Assert 1: If properties didn't change, we don't notify
+ GetRenderedBatch(oldTree, newTree1);
+ Assert.Equal(1, childComponentInstance.NotificationsCount);
+
+ // Act/Assert 2: If properties did change, we do notify
+ var batch2 = GetRenderedBatch(newTree1, newTree2);
+ var diffForChildComponent2 = batch2.UpdatedComponents.Array[1];
+ Assert.Equal(2, childComponentInstance.NotificationsCount);
+ Assert.Collection(diffForChildComponent2.CurrentState,
+ node => AssertNode.Text(node, "Notifications: 2", 0));
+ }
+
[Fact]
public void CallsDisposeOnlyOnRemovedChildComponents()
{
@@ -801,9 +854,12 @@ namespace Microsoft.AspNetCore.Blazor.Test
}
private RenderBatch GetRenderedBatch()
+ => GetRenderedBatch(oldTree, newTree);
+
+ private RenderBatch GetRenderedBatch(RenderTreeBuilder from, RenderTreeBuilder to)
{
var batchBuilder = new RenderBatchBuilder();
- diff.ApplyNewRenderTreeVersion(batchBuilder, 0, oldTree.GetNodes(), newTree.GetNodes());
+ diff.ApplyNewRenderTreeVersion(batchBuilder, 0, from.GetNodes(), to.GetNodes());
return batchBuilder.ToBatch();
}
@@ -835,6 +891,23 @@ namespace Microsoft.AspNetCore.Blazor.Test
}
}
+ private class HandlePropertiesChangedComponent : IComponent, IHandlePropertiesChanged
+ {
+ public int NotificationsCount { get; private set; }
+
+ public int IntProperty { get; set; }
+
+ public void BuildRenderTree(RenderTreeBuilder builder)
+ {
+ builder.AddText(0, $"Notifications: {NotificationsCount}");
+ }
+
+ public void OnPropertiesChanged()
+ {
+ NotificationsCount++;
+ }
+ }
+
private class DisposableComponent : IComponent, IDisposable
{
public int DisposalCount { get; private set; }
diff --git a/test/testapps/BasicTestApp/PropertiesChangedHandlerChild.cshtml b/test/testapps/BasicTestApp/PropertiesChangedHandlerChild.cshtml
new file mode 100644
index 0000000000..af7cf9f5b5
--- /dev/null
+++ b/test/testapps/BasicTestApp/PropertiesChangedHandlerChild.cshtml
@@ -0,0 +1,12 @@
+You supplied: @SuppliedValue
+I computed: @ComputedValue
+
+@functions {
+ public int SuppliedValue { get; set; }
+ private int ComputedValue { get; set; }
+
+ public override void OnPropertiesChanged()
+ {
+ ComputedValue = SuppliedValue * 2;
+ }
+}
diff --git a/test/testapps/BasicTestApp/PropertiesChangedHandlerParent.cshtml b/test/testapps/BasicTestApp/PropertiesChangedHandlerParent.cshtml
new file mode 100644
index 0000000000..89137bf9cf
--- /dev/null
+++ b/test/testapps/BasicTestApp/PropertiesChangedHandlerParent.cshtml
@@ -0,0 +1,6 @@
+
+
+
+@functions {
+ private int valueToSupply = 100;
+}