@inject IJSRuntime JSRuntime @implements IDisposable @code { [Parameter, EditorRequired] public EdgeModel Model { get; set; } = null!; [Parameter] public EventCallback DoubleClick { get; set; } [CascadingParameter] protected bool MapIsActive { get; set; } [Parameter] public EditorState EditorState { get; set; } private ElementReference Ref; private ElementReference ErrorRef; private DotNetObjectReference DotNetObj = null!; private bool IsError = false; private bool IsSetting => EditorState == EditorState.NavigationEdit || EditorState == EditorState.CreateStraighEdge || EditorState == EditorState.CreateCurveEdge || EditorState == EditorState.CreateDoubleCurveEdge; protected override async Task OnAfterRenderAsync(bool firstRender) { await base.OnAfterRenderAsync(firstRender); if (!firstRender) return; DotNetObj = DotNetObjectReference.Create(this); await JSRuntime.InvokeVoidAsync("AddEventListener", DotNetObj, Ref, "click", nameof(Click), false); await UpdatePathData(); await JSRuntime.InvokeVoidAsync("ElementSetAttribute", ErrorRef, "visibility", "hidden"); } public override async Task SetParametersAsync(ParameterView parameters) { bool updateLine = false; if (parameters.TryGetValue(nameof(Model), out EdgeModel? model)) { if (((Model?.Id ?? Guid.Empty) != (model?.Id ?? Guid.Empty))) { if (Model != null) { Model.StartNodePositionChanged -= UpdatePathData; Model.EndNodePositionChanged -= UpdatePathData; Model.ControlPoint1PositionChanged -= UpdatePathData; Model.ControlPoint2PositionChanged -= UpdatePathData; Model.ActiveChanged -= ActivedChanged; Model.ErrorChanged -= ErrorChanged; } if (model != null) { model.StartNodePositionChanged += UpdatePathData; model.EndNodePositionChanged += UpdatePathData; model.ControlPoint1PositionChanged += UpdatePathData; model.ControlPoint2PositionChanged += UpdatePathData; model.ActiveChanged += ActivedChanged; model.ErrorChanged += ErrorChanged; updateLine = true; } } } await base.SetParametersAsync(parameters); if (updateLine) await UpdatePathData(); } private async Task UpdatePathData() { var data = $"M {Model.X1} {Model.Y1}"; if (Model.TrajectoryDegree == TrajectoryDegree.One) { data = $"{data} L {(Model.X1 + Model.X2) / 2} {(Model.Y1 + Model.Y2) / 2} L {Model.X2} {Model.Y2}"; } else if (Model.TrajectoryDegree == TrajectoryDegree.Two) { data = $"{data} Q {Model.ControlPoint1X} {Model.ControlPoint1Y} {Model.X2} {Model.Y2}"; } else if (Model.TrajectoryDegree == TrajectoryDegree.Three) { data = $"{data} C {Model.ControlPoint1X} {Model.ControlPoint1Y}, {Model.ControlPoint2X} {Model.ControlPoint2Y}, {Model.X2} {Model.Y2}"; } await JSRuntime.InvokeVoidAsync("ElementSetAttribute", Ref, "d", data); if (IsError) await JSRuntime.InvokeVoidAsync("ElementSetAttribute", ErrorRef, "d", data); } private async void ActivedChanged(bool state) => await JSRuntime.InvokeVoidAsync(state ? "AddSelected" : "RemoveSelected", Ref); private async void ErrorChanged(bool state) { IsError = state; await JSRuntime.InvokeVoidAsync("ElementSetAttribute", ErrorRef, "visibility", state ? "visible" : "hidden"); await UpdatePathData(); } [JSInvokable] public void Click() => Model.Selected(); public void Dispose() { if (Model != null) { Model.StartNodePositionChanged -= UpdatePathData; Model.EndNodePositionChanged -= UpdatePathData; Model.ControlPoint1PositionChanged -= UpdatePathData; Model.ControlPoint2PositionChanged -= UpdatePathData; Model.ActiveChanged -= ActivedChanged; Model.ErrorChanged -= ErrorChanged; } if (DotNetObj != null) DotNetObj.Dispose(); GC.SuppressFinalize(this); } }