如何使用 Blazor 更改 div 元素的 类
How to change classes of a div element using Blazor
我在 cshtml 页面中有一个典型的 div 元素,格式如下:
<div id="loginErrors" class="alert alert-danger hide-errors">@(ErrorMessage)</div>
在 Blazor 之前,我通常会使用 jQuery 从 div 添加或删除 hide-errors
class。但是,Blazor 正在尝试消除对 JavaScript 的需求,而我正在尝试使用尽可能少的 JSInterop。 Blazor 有办法做到这一点吗?
所以在 Blazor 中我可以这样做:
@if (!string.IsNullOrEmpty(ErrorMessage))
{
<div id="loginErrors" class="alert alert-danger">@(ErrorMessage)</div>
}
else
{
<div id="loginErrors" class="alert alert-danger hide-errors">@(ErrorMessage)</div>
}
或使用 JSinterop :
删除请求:
await JSRuntime.Current.InvokeAsync<object>("blazorExtensions.RemoveClass", "loginErrors", "hide-errors");
函数通常是:
RemoveClass: function (id, classname) {
var tt = '#' + id;
$(tt).removeClass(classname);
}
与添加一个class类似。以上两项都有效,但如上所述。我正在尝试避免使用 JSInterop 路由,并且我不喜欢 div 元素被声明两次,即使只有一个元素会进入 DOM。
就像在普通 Razor 中一样:
@if (price>30)
{
<p>The price is too high.</p>
}
编辑
对于更新的问题,我猜你想要这个:
<div class="@((string.IsNullOrEmpty(ErrorMessage)? "hide-errors" : ""))">
这非常简单,因为您可以在 Blazor 中动态更改 html 元素的任何部分,而无需使用 Javascript。我承认,经过这么多年,我花了一点时间才摆脱旧的 Javascript 心态,但一旦你摆脱了,Blazor 就会摇摇欲坠!
在您的 html 某处使用一个变量作为您想要对其进行动态样式(或其他)修改的任何 html 元素的 class 名称(或其他属性)。
<img class="@myImageClass" src="@myImg" />
在@functions 中声明您创建的任何变量...
@functions {
string myImageClass { get; set; }
string myImg { get; set; } // Swap out the image as well if you want.
如果您想将项目设置为最初使用 OnInit()
protected override void OnInit()
{
myImageClass = "myImageVisible";
myImg = "https://www.somesite.com/ImageToStartWith.png"
}
函数中的某处将样式部分中所需的 class 更改为您 pre-defined 的内容。
private async Task DoSomething()
{
myImageClass = "myImageHidden";
myImg = "https://www.somesite.com/NewImageToSwapIn.png"
//Not sure what the point of swapping an image on a hidden element is
//but you get the idea. You can change anything you want anytime.
}
不要忘记预先定义一些您要使用的样式。
<style>
.myImageVisible {
display: block;
}
.myImageHidden{
display: none;
}
</style>
尽情享受吧。 :)
对于完全怪胎(我)创建一个剃须刀组件(xaml 情人梦):
用法示例
<ContentView Size="Small" IsVisible="@IsOnline">
<img src="@myImg" />
</ContentView>
结果:div 应用了适当的 class,class='size-small'
用于 Size="Small"
。
您可以向此类组件添加任何参数,并根据您的逻辑在内部更改 classes,保持主页干净。
ContentView.razor
@if (IsVisible)
{
<div class="@sizeClass"> @ChildContent</div>
}
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
[Parameter]
public bool IsVisible { get; set; } = true;
[Parameter]
public string Size {
get
{
return _size.ToString();
}
set
{
_size = Enum.Parse<MySize>(value);
switch (_size)
{
case MySize.Big:
sizeClass = "size-big";
break;
case MySize.Small:
sizeClass = "size-small";
break;
default:
sizeClass = "";
break;
}
}
}
private MySize _size;
private string sizeClass;
public enum MySize
{
Default,
Small,
Big
}
}
这是我在控制 UI 特定元素(例如突出显示已单击的元素)的上下文中问自己的一个问题,以防它们很多,例如列表。
两种常见方式(如其他人所述)是:
- 在元素中绑定一个 page/component 字符串 属性 class="@someProp some-other-class..." 属性,可用于设置多个 classes(因为它只是一个字符串)或添加多个此类属性(用于更精细的条件控制)。
- 创建一个专用组件,将所有必需的属性绑定到 classes 或 CSS 值。
但我想我想到了第三种方法,一种“介于两者之间”的技术,它提供了一个非常强大的 UI 对象绑定控件(甚至是双向绑定),而无需处理单独的组件。因为有时候需要手动触发父组件StateHasChanged(),比如父子组件之间存在各种依赖关系,但是视觉状态机制不会自动刷新。
只需创建一个包装器 class,用您想要控制的 CSS 值表示项目作为其属性。在同一个 page/component @code 部分或某个共享文件夹中。
例如,我有一个 Slide 对象的列表,由 在视觉上表示(并因此包装) 卡片 对象,用户可以单击该对象 select 并进行编辑。
商品型号:
public class Slide {
public int SlideId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int SortIndex{ get; set; }
}
项目包装模型:
public class Card {
Slide Slide { get; set; }
public string SelectedCssClass { get; set; }
public string SomeOtherCssClass { get; set; }
public void Reset() {
SelectedCssClass = "";
{
}
所以在组件初始化的时候,在OnIntialized()方法中(或者OnInitializedAsync( ) 如果您获取并等待数据列表)我用一个新的包装器对象包装每个项目。然后在 @foreach() { } 循环中,列出包装的项目,我附上一个 @onclick 事件处理程序到每个 div/card,传递该卡片对象的引用:
@foreach (Card card in Cards)
{
<div class="card @card.SelectedCssClass" @onclick="@(e => setSlideToEdit(card))"
}
在 setSlideToEdit(card) { } 函数中我可以重置之前 selected 幻灯片的样式(存储在一些 属性) 通过简单地调用 card.Reset() 方法并让绑定完成工作,然后使用新的并将 card.SelectedCssClass 属性 设置为我的愿望(或添加另一种专用方法来设置预定义方法) .
我在 cshtml 页面中有一个典型的 div 元素,格式如下:
<div id="loginErrors" class="alert alert-danger hide-errors">@(ErrorMessage)</div>
在 Blazor 之前,我通常会使用 jQuery 从 div 添加或删除 hide-errors
class。但是,Blazor 正在尝试消除对 JavaScript 的需求,而我正在尝试使用尽可能少的 JSInterop。 Blazor 有办法做到这一点吗?
所以在 Blazor 中我可以这样做:
@if (!string.IsNullOrEmpty(ErrorMessage))
{
<div id="loginErrors" class="alert alert-danger">@(ErrorMessage)</div>
}
else
{
<div id="loginErrors" class="alert alert-danger hide-errors">@(ErrorMessage)</div>
}
或使用 JSinterop :
删除请求:
await JSRuntime.Current.InvokeAsync<object>("blazorExtensions.RemoveClass", "loginErrors", "hide-errors");
函数通常是:
RemoveClass: function (id, classname) {
var tt = '#' + id;
$(tt).removeClass(classname);
}
与添加一个class类似。以上两项都有效,但如上所述。我正在尝试避免使用 JSInterop 路由,并且我不喜欢 div 元素被声明两次,即使只有一个元素会进入 DOM。
就像在普通 Razor 中一样:
@if (price>30)
{
<p>The price is too high.</p>
}
编辑 对于更新的问题,我猜你想要这个:
<div class="@((string.IsNullOrEmpty(ErrorMessage)? "hide-errors" : ""))">
这非常简单,因为您可以在 Blazor 中动态更改 html 元素的任何部分,而无需使用 Javascript。我承认,经过这么多年,我花了一点时间才摆脱旧的 Javascript 心态,但一旦你摆脱了,Blazor 就会摇摇欲坠!
在您的 html 某处使用一个变量作为您想要对其进行动态样式(或其他)修改的任何 html 元素的 class 名称(或其他属性)。
<img class="@myImageClass" src="@myImg" />
在@functions 中声明您创建的任何变量...
@functions {
string myImageClass { get; set; }
string myImg { get; set; } // Swap out the image as well if you want.
如果您想将项目设置为最初使用 OnInit()
protected override void OnInit()
{
myImageClass = "myImageVisible";
myImg = "https://www.somesite.com/ImageToStartWith.png"
}
函数中的某处将样式部分中所需的 class 更改为您 pre-defined 的内容。
private async Task DoSomething()
{
myImageClass = "myImageHidden";
myImg = "https://www.somesite.com/NewImageToSwapIn.png"
//Not sure what the point of swapping an image on a hidden element is
//but you get the idea. You can change anything you want anytime.
}
不要忘记预先定义一些您要使用的样式。
<style>
.myImageVisible {
display: block;
}
.myImageHidden{
display: none;
}
</style>
尽情享受吧。 :)
对于完全怪胎(我)创建一个剃须刀组件(xaml 情人梦):
用法示例
<ContentView Size="Small" IsVisible="@IsOnline">
<img src="@myImg" />
</ContentView>
结果:div 应用了适当的 class,class='size-small'
用于 Size="Small"
。
您可以向此类组件添加任何参数,并根据您的逻辑在内部更改 classes,保持主页干净。
ContentView.razor
@if (IsVisible)
{
<div class="@sizeClass"> @ChildContent</div>
}
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
[Parameter]
public bool IsVisible { get; set; } = true;
[Parameter]
public string Size {
get
{
return _size.ToString();
}
set
{
_size = Enum.Parse<MySize>(value);
switch (_size)
{
case MySize.Big:
sizeClass = "size-big";
break;
case MySize.Small:
sizeClass = "size-small";
break;
default:
sizeClass = "";
break;
}
}
}
private MySize _size;
private string sizeClass;
public enum MySize
{
Default,
Small,
Big
}
}
这是我在控制 UI 特定元素(例如突出显示已单击的元素)的上下文中问自己的一个问题,以防它们很多,例如列表。
两种常见方式(如其他人所述)是:
- 在元素中绑定一个 page/component 字符串 属性 class="@someProp some-other-class..." 属性,可用于设置多个 classes(因为它只是一个字符串)或添加多个此类属性(用于更精细的条件控制)。
- 创建一个专用组件,将所有必需的属性绑定到 classes 或 CSS 值。
但我想我想到了第三种方法,一种“介于两者之间”的技术,它提供了一个非常强大的 UI 对象绑定控件(甚至是双向绑定),而无需处理单独的组件。因为有时候需要手动触发父组件StateHasChanged(),比如父子组件之间存在各种依赖关系,但是视觉状态机制不会自动刷新。
只需创建一个包装器 class,用您想要控制的 CSS 值表示项目作为其属性。在同一个 page/component @code 部分或某个共享文件夹中。
例如,我有一个 Slide 对象的列表,由 在视觉上表示(并因此包装) 卡片 对象,用户可以单击该对象 select 并进行编辑。
商品型号:
public class Slide {
public int SlideId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int SortIndex{ get; set; }
}
项目包装模型:
public class Card {
Slide Slide { get; set; }
public string SelectedCssClass { get; set; }
public string SomeOtherCssClass { get; set; }
public void Reset() {
SelectedCssClass = "";
{
}
所以在组件初始化的时候,在OnIntialized()方法中(或者OnInitializedAsync( ) 如果您获取并等待数据列表)我用一个新的包装器对象包装每个项目。然后在 @foreach() { } 循环中,列出包装的项目,我附上一个 @onclick 事件处理程序到每个 div/card,传递该卡片对象的引用:
@foreach (Card card in Cards)
{
<div class="card @card.SelectedCssClass" @onclick="@(e => setSlideToEdit(card))"
}
在 setSlideToEdit(card) { } 函数中我可以重置之前 selected 幻灯片的样式(存储在一些 属性) 通过简单地调用 card.Reset() 方法并让绑定完成工作,然后使用新的并将 card.SelectedCssClass 属性 设置为我的愿望(或添加另一种专用方法来设置预定义方法) .