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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Microsoft.AspNetCore.Blazor.Components;
|
|
||||||
using Microsoft.AspNetCore.Blazor.Rendering;
|
using Microsoft.AspNetCore.Blazor.Rendering;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Blazor.RenderTree
|
namespace Microsoft.AspNetCore.Blazor.RenderTree
|
||||||
|
|
@ -339,7 +338,7 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
|
||||||
throw new InvalidOperationException($"Child component already exists during {nameof(InstantiateChildComponents)}");
|
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>
|
/// <summary>
|
||||||
/// Updates the visible UI to display the supplied <paramref name="renderTree"/>
|
/// Updates the visible UI to display the supplied <paramref name="renderTree"/>
|
||||||
/// at the location corresponding to the <paramref name="componentId"/>.
|
/// 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)
|
protected void DispatchEvent(int componentId, int renderTreeIndex, UIEventArgs eventArgs)
|
||||||
=> GetRequiredComponentState(componentId).DispatchEvent(renderTreeIndex, 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)
|
private ComponentState GetRequiredComponentState(int componentId)
|
||||||
=> _componentStateById.TryGetValue(componentId, out var componentState)
|
=> _componentStateById.TryGetValue(componentId, out var componentState)
|
||||||
? componentState
|
? componentState
|
||||||
: throw new ArgumentException($"The renderer does not have a component with ID {componentId}.");
|
: 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));
|
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]
|
[Fact]
|
||||||
public void RetainsChildComponentsForExistingNodes()
|
public void RetainsChildComponentsForExistingNodes()
|
||||||
{
|
{
|
||||||
|
|
@ -722,6 +755,12 @@ namespace Microsoft.AspNetCore.Blazor.Test
|
||||||
|
|
||||||
private class FakeComponent : IComponent
|
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)
|
public void BuildRenderTree(RenderTreeBuilder builder)
|
||||||
=> throw new NotImplementedException();
|
=> throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue