diff --git a/docs/content/features/parameters.md b/docs/content/features/parameters.md
index b9d4ad1..7b13d18 100644
--- a/docs/content/features/parameters.md
+++ b/docs/content/features/parameters.md
@@ -106,6 +106,25 @@ or
```
+You can also use `key` to force re-render of your component:
+
+```razor
+
+```
+
+Now, whenever `Model.Items` changes, Hydro will re-render the component `Items` and pass new parameter.
+
+### Key attribute behavior in the UI
+
+By default, when a component with the same key attribute is
+re-rendered, its HTML is replaced (not morphed). Since `key` is also used to force re-render of the component,
+there might be a case where you want to morph the component HTML instead, for example when the rendered component
+is the one where might be the focus. To do that, use `key-behavior` attribute:
+
+```razor
+
+```
+
## Caching
Let's imagine you need to show list of customers in a table. It's good to use caching per request for such rows data,
diff --git a/src/HydroComponent.cs b/src/HydroComponent.cs
index eb26b5b..5f88662 100644
--- a/src/HydroComponent.cs
+++ b/src/HydroComponent.cs
@@ -59,6 +59,12 @@ public abstract class HydroComponent : ViewComponent
///
[JsonProperty]
protected string Key { get; private set; }
+
+ ///
+ /// Component's HTML behavior when the key changes
+ ///
+ [JsonProperty]
+ protected KeyBehavior KeyBehavior { get; private set; }
///
/// Default identifier used to specify place of the page to replace when during location change
@@ -138,12 +144,14 @@ private void ConfigurePolls()
///
/// An object with component parameters
/// Local identifier to distinguish components of same type
- public async Task InvokeAsync(object parameters = null, string key = null)
+ /// Component's HTML behavior when the key changes
+ public async Task InvokeAsync(object parameters = null, string key = null, KeyBehavior keyBehavior = KeyBehavior.Replace)
{
ApplyParameters(parameters);
ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = null;
Key = key;
+ KeyBehavior = keyBehavior;
var persistentState = HttpContext.RequestServices.GetService();
_options = HttpContext.RequestServices.GetService();
@@ -430,7 +438,7 @@ private async Task RenderOnlineNestedComponent(IPersistentState persiste
if (IsComponentIdRendered(componentId))
{
- return GetComponentPlaceholderTemplate(componentId, Key);
+ return GetComponentPlaceholderTemplate(componentId, Key, KeyBehavior);
}
if (!await AuthorizeAsync())
@@ -444,8 +452,12 @@ private async Task RenderOnlineNestedComponent(IPersistentState persiste
return await GenerateComponentHtml(componentId, persistentState, includeScripts: true);
}
- private static string GetComponentPlaceholderTemplate(string componentId, string key) =>
- $"";
+ private static string GetComponentPlaceholderTemplate(string componentId, string key, KeyBehavior keyBehavior)
+ {
+ var useKey = !string.IsNullOrWhiteSpace(key) && keyBehavior == KeyBehavior.Replace;
+
+ return $"";
+ }
private async Task RenderStaticComponent(IPersistentState persistentState)
{
@@ -496,7 +508,7 @@ private async Task GenerateComponentHtml(string componentId, IPersistent
rootElement.SetAttributeValue("hydro-name", GetType().Name);
rootElement.SetAttributeValue("x-data", "hydro");
- if (!string.IsNullOrWhiteSpace(Key))
+ if (!string.IsNullOrWhiteSpace(Key) && KeyBehavior == KeyBehavior.Replace)
{
rootElement.SetAttributeValue("key", Key);
}
diff --git a/src/KeyBehavior.cs b/src/KeyBehavior.cs
new file mode 100644
index 0000000..bfde531
--- /dev/null
+++ b/src/KeyBehavior.cs
@@ -0,0 +1,17 @@
+namespace Hydro;
+
+///
+/// Defines the component behavior when key changes
+///
+public enum KeyBehavior
+{
+ ///
+ /// Replace the component's HTML
+ ///
+ Replace,
+
+ ///
+ /// Morph the component's HTML
+ ///
+ Morph
+}
\ No newline at end of file
diff --git a/src/TagHelpers/HydroComponentTagHelper.cs b/src/TagHelpers/HydroComponentTagHelper.cs
index 3a7b7d8..10230cc 100644
--- a/src/TagHelpers/HydroComponentTagHelper.cs
+++ b/src/TagHelpers/HydroComponentTagHelper.cs
@@ -68,10 +68,10 @@ public IDictionary ParametersDictionary
public int? Delay { get; set; } = 0;
///
- ///
+ /// Component's HTML behavior when the key changes
///
- [HtmlAttributeName("run")]
- public bool Run { get; set; }
+ [HtmlAttributeName("key-behavior")]
+ public KeyBehavior KeyBehavior { get; set; } = KeyBehavior.Replace;
///
/// Processes the tag helper
@@ -89,7 +89,8 @@ public override async Task ProcessAsync(TagHelperContext context, TagHelperOutpu
var componentHtml = await viewComponentHelper.InvokeAsync(Name, new
{
parameters = Parameters ?? _parameters,
- key = Key
+ key = Key,
+ keyBehavior = KeyBehavior
});
output.Content.SetHtmlContent(componentHtml);