如何使用Blazor更改div元素的类

时间:2019-01-08 08:29:00

标签: blazor

我在cshtml页面中具有以下形式的典型div元素:

<div id="loginErrors" class="alert alert-danger hide-errors">@(ErrorMessage)</div>

Blazor之前,我通常会使用jQuery在div中添加或删除hide-errors类。但是,Blazor试图消除对JavaScript的需求,而我正在尝试使用尽可能少的JSInterop。开拓者有办法做到这一点吗?

所以在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);
}

与用于添加类的类似。以上两项工作均已完成,但如上所述。我试图避免JSInterop路由,并且我不喜欢将div元素声明两次,即使只有一个会进入DOM。

4 个答案:

答案 0 :(得分:1)

这非常容易,因为您可以使用Javascript在Blazor中动态更改html元素的任何部分而无需。我承认,经过了这么多年,我花了一些时间才摆脱了旧的Javascript心态,但是一旦您这样做,Blazor就会摇摇欲坠!

在您的html某处,将变量用作要对其进行动态样式(或其他)修改的任何html元素的类名(或其他属性)。

    <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"

     }

将函数中的某处更改为所需的类,以更改为您在样式部分中预定义的内容。

    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>

享受。 :)

答案 1 :(得分:0)

就像在普通剃刀中一样:

@if (price>30)
{
    <p>The price is too high.</p>
}

编辑 对于更新的问题,我想您想要这样做:

<div class="@((string.IsNullOrEmpty(ErrorMessage)? "hide-errors" : ""))">

答案 2 :(得分:0)

对于完整的怪胎(我),创建一个剃刀组件(xaml情人梦):

示例用法

<ContentView Size="Small" IsVisible="@IsOnline">

 <img src="@myImg" />

</ContentView>

结果:应用了适当类的div,class='size-small'代表Size="Small"

您可以向该组件添加任何参数,并根据逻辑更改内部类,以保持主页整洁。

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
    }

}

答案 3 :(得分:0)

这是我在控制特定元素的 UI(例如突出显示被点击的元素)的上下文中问自己的一个问题,以防它们中有很多,例如列表。

2 种常见方式(正如其他人提到的)是:

  1. 在元素class="@someProp some-other-class..." 属性中绑定一个页面/组件字符串属性,可以用来设置多个类(因为它只是一个字符串)或添加多个这样的属性(为了更好的条件控制)。
  2. 创建专用组件,其中包含将类或 CSS 值绑定到的所有必需属性。

但我想我想出了第三种方式,一种“介于两者之间”的技术,它提供了一个非常强大的 UI 控件和对象绑定(甚至是 2 路绑定),而无需处理单独的组件。因为有时候你需要手动触发父组件StateHasChanged(),比如父子组件之间存在各种依赖,而视觉状态机制却没有启动以自动刷新。

只需创建一个包装类,用您想要控制的 CSS 值作为其属性来表示项目。在同一页面/组件@code 部分或某个共享文件夹中。

例如,我有一个 Slide 对象列表,用 卡片 直观地表示(并因此包装) em> 对象,用户可以点击该对象进行选择和编辑。

物品模型:

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) { } 函数中,我可以通过简单地调用 来重置以前选择的幻灯片的样式(存储在某些属性中) card.Reset() 方法并让绑定完成工作,然后使用新方法并将 card.SelectedCssClass 属性设置为我的希望(或添加另一种专用方法来设置预定义的方法)。