# 组件关联

### 父组件

如果是 `.razor` 组件，需要手动使用 `CascadingValue` 传入当前组件

{% code title="List.razor" %}

```cshtml
@inherits BlazorComponentBase

<CascadingValue Value="this">
    <ul @attributes="AdditionalAttributes">@ChildContent</ul>
</CascadingValue>
```

{% endcode %}

如果是组件类，仅需要定义 `ParentComponent` 特性即可

```csharp
[ParentComponent]
public class List : BlazorComponentBase
{
}
```

### 子组件

定义 `ChildComponent` 特性关联父组件

{% code title="ListItem.razor" %}

```cshtml
@inherits BlazorComponentBase
@attribute [ChildComponent(typeof(List))]

<!--.NET 7-->
@attribute [ChildComponent<List>]

<li @attributes="@AdditionalAttributes">
    @ChildContent
</li>

@code{
    [CascadingParameter]public List CascadedList { get; set; }
    
    protected override void BuildCssClass(ICssClassBuilder builder)
    {
        if(CascadedList.Active)
        {
            //..
        }
    }
}
```

{% endcode %}

{% code title="ListItem.cs" %}

```csharp
[ChildComponent(typeof(List))]
//[ChidlComponent<List>] // .NET 7
public class ListItem : BlazorComponentBase
{
    [CascadingParameter]public List CascadedList { get; set; }
    
    protected override void BuildCssClass(ICssClassBuilder builder)
    {
        if(CascadedList.Active)
        {
            //..
        }
    }
}
```

{% endcode %}

组件 `ListItem` 必须放在 `List` 组件中，否则将抛出异常

```cshtml
<List>
    <ListItem>...</ListItem>
</List>

<!--throw exception-->
<ListItem />
```

### Optional

`true` 时将忽略强制关联，不抛出异常

{% code title="ListItem.razor" %}

```cshtml
@inherits BlazorComponentBase
@attribute [ChildComponent(typeof(List))]

<!--For .NET 7 can use generic attribute-->
@attribute [ChildComponent<List>]

<li @attributes="@AdditionalAttributes">
    @ChildContent
</li>

@code{
    [CascadingParameter]public List CascadedList { get; set; }
    
    protected override void BuildCssClass(ICssClassBuilder builder)
    {
        if(CascadedList.Active)
        {
            //..
        }
    }
}
```

{% endcode %}

{% code title="ListItem.cs" %}

```csharp
[ChildComponent(typeof(List), Optional = true)]
//[ChidlComponent<List>(Optional = true)] // for .net7
public class ListItem : BlazorComponentBase
{
    //This instance may be null
    [CascadingParameter]public List? CascadedList { get; set; }
    
    protected override void BuildCssClass(ICssClassBuilder builder)
    {
        if(CascadedList is not null && CascadedList.Active)
        {
            //..
        }
    }
}
```

{% endcode %}

```cshtml
<!--never throw exception-->
<ListItem />
```
