Begin on setting properties on child components
This commit is contained in:
parent
0aa164073d
commit
9dcb1c4fc4
|
|
@ -2,7 +2,6 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Blazor.Components;
|
||||
using Microsoft.AspNetCore.Blazor.Rendering;
|
||||
|
||||
namespace Microsoft.AspNetCore.Blazor.RenderTree
|
||||
|
|
@ -339,7 +338,7 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
|
|||
throw new InvalidOperationException($"Child component already exists during {nameof(InstantiateChildComponents)}");
|
||||
}
|
||||
|
||||
_renderer.InstantiateChildComponent(ref nodes[i]);
|
||||
_renderer.InstantiateChildComponent(nodes, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,23 +42,6 @@ namespace Microsoft.AspNetCore.Blazor.Rendering
|
|||
}
|
||||
}
|
||||
|
||||
internal void InstantiateChildComponent(ref RenderTreeNode node)
|
||||
{
|
||||
if (node.NodeType != RenderTreeNodeType.Component)
|
||||
{
|
||||
throw new ArgumentException($"The node's {nameof(RenderTreeNode.NodeType)} property must equal {RenderTreeNodeType.Component}", nameof(node));
|
||||
}
|
||||
|
||||
if (node.Component != null)
|
||||
{
|
||||
throw new ArgumentException($"The node already has a non-null component instance", nameof(node));
|
||||
}
|
||||
|
||||
var newComponent = (IComponent)Activator.CreateInstance(node.ComponentType);
|
||||
var newComponentId = AssignComponentId(newComponent);
|
||||
node.SetChildComponentInstance(newComponentId, newComponent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the visible UI to display the supplied <paramref name="renderTree"/>
|
||||
/// at the location corresponding to the <paramref name="componentId"/>.
|
||||
|
|
@ -84,9 +67,46 @@ namespace Microsoft.AspNetCore.Blazor.Rendering
|
|||
protected void DispatchEvent(int componentId, int renderTreeIndex, UIEventArgs eventArgs)
|
||||
=> GetRequiredComponentState(componentId).DispatchEvent(renderTreeIndex, eventArgs);
|
||||
|
||||
internal void InstantiateChildComponent(RenderTreeNode[] nodes, int componentNodeIndex)
|
||||
{
|
||||
ref var node = ref nodes[componentNodeIndex];
|
||||
if (node.NodeType != RenderTreeNodeType.Component)
|
||||
{
|
||||
throw new ArgumentException($"The node's {nameof(RenderTreeNode.NodeType)} property must equal {RenderTreeNodeType.Component}", nameof(node));
|
||||
}
|
||||
|
||||
if (node.Component != null)
|
||||
{
|
||||
throw new ArgumentException($"The node already has a non-null component instance", nameof(node));
|
||||
}
|
||||
|
||||
var newComponent = (IComponent)Activator.CreateInstance(node.ComponentType);
|
||||
var newComponentId = AssignComponentId(newComponent);
|
||||
node.SetChildComponentInstance(newComponentId, newComponent);
|
||||
SetPropertiesOnComponent(nodes, componentNodeIndex);
|
||||
}
|
||||
|
||||
private ComponentState GetRequiredComponentState(int componentId)
|
||||
=> _componentStateById.TryGetValue(componentId, out var componentState)
|
||||
? componentState
|
||||
: throw new ArgumentException($"The renderer does not have a component with ID {componentId}.");
|
||||
|
||||
private void SetPropertiesOnComponent(RenderTreeNode[] nodes, int componentNodeIndex)
|
||||
{
|
||||
ref var componentNode = ref nodes[componentNodeIndex];
|
||||
var component = componentNode.Component;
|
||||
var descendantsEndIndex = componentNode.ElementDescendantsEndIndex;
|
||||
for (var attributeNodeIndex = componentNodeIndex + 1; attributeNodeIndex <= descendantsEndIndex; attributeNodeIndex++)
|
||||
{
|
||||
SetPropertyOnComponent(component, nodes[attributeNodeIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetPropertyOnComponent(IComponent component, in RenderTreeNode attributeNode)
|
||||
{
|
||||
// TODO: Cache the reflection
|
||||
var property = component.GetType().GetProperty(attributeNode.AttributeName);
|
||||
property.SetValue(component, attributeNode.AttributeValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -674,6 +674,39 @@ namespace Microsoft.AspNetCore.Blazor.Test
|
|||
entry => AssertEdit(entry, RenderTreeEditType.StepOut, 0));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetsKnownPropertiesOnChildComponents()
|
||||
{
|
||||
// Arrange
|
||||
var renderer = new FakeRenderer();
|
||||
var oldTree = new RenderTreeBuilder(renderer);
|
||||
var newTree = new RenderTreeBuilder(renderer);
|
||||
var diff = new RenderTreeDiffComputer(renderer);
|
||||
var testObject = new object();
|
||||
newTree.OpenComponentElement<FakeComponent>(0);
|
||||
//newTree.AddAttribute(1, nameof(FakeComponent.IntProperty), 123);
|
||||
newTree.AddAttribute(2, nameof(FakeComponent.StringProperty), "some string");
|
||||
//newTree.AddAttribute(3, nameof(FakeComponent.ObjectProperty), testObject);
|
||||
newTree.CloseElement();
|
||||
|
||||
// Act
|
||||
var result = diff.ApplyNewRenderTreeVersion(oldTree.GetNodes(), newTree.GetNodes());
|
||||
var componentInstance = newTree.GetNodes().First().Component as FakeComponent;
|
||||
|
||||
// Assert
|
||||
AssertEdit(result.Edits.Single(), RenderTreeEditType.PrependNode, 0);
|
||||
Assert.NotNull(componentInstance);
|
||||
//Assert.Equal(123, componentInstance.IntProperty);
|
||||
Assert.Equal("some string", componentInstance.StringProperty);
|
||||
//Assert.Same(testObject, componentInstance.ObjectProperty);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RejectsUnknownPropertiesOnChildComponents()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RetainsChildComponentsForExistingNodes()
|
||||
{
|
||||
|
|
@ -722,6 +755,12 @@ namespace Microsoft.AspNetCore.Blazor.Test
|
|||
|
||||
private class FakeComponent : IComponent
|
||||
{
|
||||
public int IntProperty { get; set; }
|
||||
public string StringProperty { get; set; }
|
||||
public object ObjectProperty { get; set; }
|
||||
public string ReadonlyProperty { get; private set; }
|
||||
private string PrivateProperty { get; set; }
|
||||
|
||||
public void BuildRenderTree(RenderTreeBuilder builder)
|
||||
=> throw new NotImplementedException();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue