我在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。
答案 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 种常见方式(正如其他人提到的)是:
但我想我想出了第三种方式,一种“介于两者之间”的技术,它提供了一个非常强大的 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 属性设置为我的希望(或添加另一种专用方法来设置预定义的方法)。