3

我尝试在 Blazor webassembly 页面中使用 FullCalendar。任何人都知道如何在 Blazor 中使用 FullCalendar ??? 任何人都可以帮助我吗?

我在 libman.json 中包含 FullCalendar

   {
      "library": "@fullcalendar/core",
      "provider": "unpkg",
      "destination": "wwwroot/lib/fullCalendar"
    }

在 wwwroot/index.html

   <script src="_framework/blazor.webassembly.js"></script>
   <script src="exampleJsInterop.js"></script>

wwwroot文件夹中的我的js文件“exampleJsInterop.js”

window.exampleJsFunctions = {

    showPrompt: function (text) {
        return prompt(text, 'Type your name here');
    },
    displayWelcome: function (welcomeMessage) {
        document.getElementById('welcome').innerText = welcomeMessage;
    },

    calendar: function () {
        document.getElementById("#calendar").fullCalendar({
            schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
            editable: false,
            allDaySlot: true,
            eventLimit: true,
            axisFormat: 'HH:mm',
            slotLabelFormat: 'HH:mm',
            aspectRatio: 2,
            header: {
                left: 'today prev,next',
                center: 'title',
                right: 'month '
            },
            //defaultView: 'timelineDay',
            selectable: true,
        });
    }
    
};

剃刀页面

@page "/fullCalendar"
@inject IJSRuntime JsRuntime;

<h1>FullCalendar</h1>

<button type="button" class="btn btn-primary" @onclick="test">
    Bouton test
</button>

<div class="container">
    <div id='calendar'></div>
</div>

@code {
      private async void test() {
        await JsRuntime.InvokeVoidAsync("exampleJsFunctions.calendar");
    }
}

代码有什么问题?

错误 :

(Microsoft.JSInterop.JSException: $ is not** defined)   
>main.js:1 
Failed to load resource: the server responded with a status of 404 (Not Found)
    blazor.webassembly.js:1 Debugging hotkey: Shift+Alt+D (when application has focus)
    favicon.ico:1 Failed to load resource: the server responded with a status of 404 (Not Found)
    blazor.webassembly.js:1 WASM: 
    d.printErr @ blazor.webassembly.js:1
    put_char @ mono.js:1
    write @ mono.js:1
    write @ mono.js:1
    doWritev @ mono.js:1
    ___syscall146 @ mono.js:1
    Module._mono_background_exec @ mono.js:1
    pump_message @ mono.js:1
    setTimeout (async)
    _schedule_background_exec @ mono.js:1
    Module._mono_wasm_invoke_method @ mono.js:1
    callMethod @ blazor.webassembly.js:1
    beginInvokeDotNetFromJS @ blazor.webassembly.js:1
    l @ blazor.webassembly.js:1
    e.invokeMethodAsync @ blazor.webassembly.js:1
    (anonymous) @ blazor.webassembly.js:1
    t.dispatchEvent @ blazor.webassembly.js:1
    (anonymous) @ blazor.webassembly.js:1
    (anonymous) @ blazor.webassembly.js:1
    e.onGlobalEvent @ blazor.webassembly.js:1
    Show 26 more frames
    blazor.webassembly.js:1 WASM: Unhandled Exception:
    d.printErr @ blazor.webassembly.js:1
    put_char @ mono.js:1
    write @ mono.js:1
    write @ mono.js:1
    doWritev @ mono.js:1
    ___syscall146 @ mono.js:1
    Module._mono_background_exec @ mono.js:1
    pump_message @ mono.js:1
    setTimeout (async)
    _schedule_background_exec @ mono.js:1
    Module._mono_wasm_invoke_method @ mono.js:1
    callMethod @ blazor.webassembly.js:1
    beginInvokeDotNetFromJS @ blazor.webassembly.js:1
    l @ blazor.webassembly.js:1
    e.invokeMethodAsync @ blazor.webassembly.js:1
    (anonymous) @ blazor.webassembly.js:1
    t.dispatchEvent @ blazor.webassembly.js:1
    (anonymous) @ blazor.webassembly.js:1
    (anonymous) @ blazor.webassembly.js:1
    e.onGlobalEvent @ blazor.webassembly.js:1
    Show 26 more frames
    **blazor.webassembly.js:1 WASM: Microsoft.JSInterop.JSException: $ is not** defined
    d.printErr @ blazor.webassembly.js:1
    put_char @ mono.js:1
    write @ mono.js:1
    write @ mono.js:1
    doWritev @ mono.js:1
    ___syscall146 @ mono.js:1
    Module._mono_background_exec @ mono.js:1
    pump_message @ mono.js:1
    setTimeout (async)
    _schedule_background_exec @ mono.js:1
    Module._mono_wasm_invoke_method @ mono.js:1
    callMethod @ blazor.webassembly.js:1
    beginInvokeDotNetFromJS @ blazor.webassembly.js:1
    l @ blazor.webassembly.js:1
    e.invokeMethodAsync @ blazor.webassembly.js:1
    (anonymous) @ blazor.webassembly.js:1
    t.dispatchEvent @ blazor.webassembly.js:1
    (anonymous) @ blazor.webassembly.js:1
    (anonymous) @ blazor.webassembly.js:1
    e.onGlobalEvent @ blazor.webassembly.js:1
    Show 26 more frames
    blazor.webassembly.js:1 WASM: ReferenceError: $ is not defined
    d.printErr @ blazor.webassembly.js:1
    put_char @ mono.js:1
    write @ mono.js:1
    write @ mono.js:1
    doWritev @ mono.js:1
    ___syscall146 @ mono.js:1
    Module._mono_background_exec @ mono.js:1
    pump_message @ mono.js:1
    setTimeout (async)
    _schedule_background_exec @ mono.js:1
    Module._mono_wasm_invoke_method @ mono.js:1
    callMethod @ blazor.webassembly.js:1
    beginInvokeDotNetFromJS @ blazor.webassembly.js:1
    l @ blazor.webassembly.js:1
    e.invokeMethodAsync @ blazor.webassembly.js:1
    (anonymous) @ blazor.webassembly.js:1
    t.dispatchEvent @ blazor.webassembly.js:1
    (anonymous) @ blazor.webassembly.js:1
    (anonymous) @ blazor.webassembly.js:1
    e.onGlobalEvent @ blazor.webassembly.js:1
    Show 26 more frames
    blazor.webassembly.js:1 WASM:     at testDan (http://localhost:53863/:30:17)
    d.printErr @ blazor.webassembly.js:1
    put_char @ mono.js:1
    write @ mono.js:1
    write @ mono.js:1
    doWritev @ mono.js:1
    ___syscall146 @ mono.js:1
    Module._mono_background_exec @ mono.js:1
    pump_message @ mono.js:1
    setTimeout (async)
    _schedule_background_exec @ mono.js:1
4

1 回答 1

1

经过一周的工作,我设法让FullCalendar 版本 4在 blazor net5 中运行。

日历选项.cs

using System;
using System.Collections.Generic;

namespace SmartApp.Components
{
    public class CalendarOptions
    {
        public string Id { get; set; }
        public string DefaultView { get; set; } = CalendarView.ListWeek;
        public DateTime DefaultDate { get; set; } = DateTime.Now;
        public List<CalendarEvent> CalendarEvents { get; set; } = new List<CalendarEvent>();
    }

    public class CalendarEvent
    {
        public string Identifier { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public DateTime Start { get; set; }
        public DateTime? End { get; set; }
        public string Url { get; set; } = string.Empty;
        public string SolidColor { get; set; }
        public string DotColor { get; set; }

        public string ClassName => $"{(string.IsNullOrEmpty(SolidColor) ? "" : $"fc-event-solid-{SolidColor}")} " +
                                   $"{(string.IsNullOrEmpty(DotColor) ? "" : $"fc-event-{DotColor}")}";

        public CalendarEventStatus Status { get; set; }
    }

    public class CalendarView
    {
        public static string DayGridMonth = "dayGridMonth";
        public static string TimeGridWeek = "timeGridWeek";
        public static string TimeGridDay = "timeGridDay";
        public static string ListWeek = "listWeek";
    }

    public class CalendarEventSolidColor
    {
        public static string Primary = "primary";
        public static string Warning = "warning";
        public static string Error = "error";
        public static string Success = "success";
        public static string Info = "info";
    }

    public class CalendarEventDotColor
    {
        public static string Primary = "primary";
        public static string Warning = "warning";
        public static string Error = "error";
        public static string Success = "success";
        public static string Info = "info";
        public static string Light = "light";
    }

    public enum CalendarEventStatus
    {
        Deleted = 0,
        Active = 1,
        Changed = 2
    }
}

InputCalendar.razor这是一个可重用的组件

@namespace SmartApp.Components

@inject IJSRuntime JSRuntime

<div id="@Id"></div>

@code {
    string _id;
    [Parameter]
    public string Id
    {
        get => _id ?? $"Calendar_{_uid}";
        set => _id = value;
    }

    [Parameter]
    public List<CalendarEvent> Events { get; set; }

    [Parameter]
    public string View { get; set; } = CalendarView.ListWeek;

    [Parameter]
    public EventCallback<List<CalendarEvent>> EventsChanged { get; set; }


    readonly string _uid = Guid.NewGuid().ToString().ToLower().Replace("-", "");

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await JSRuntime.InvokeVoidAsync("removeContent", $"#{Id}");

        var options = new CalendarOptions
        {
            Id = Id,
            DefaultView = View,
            CalendarEvents = Events.Where(r => r.Status == CalendarEventStatus.Active).ToList()
        };

        await JSRuntime.InvokeVoidAsync("FullCalendarInterop.init", options, DotNetObjectReference.Create(this));

        await base.OnAfterRenderAsync(firstRender);
    }

    [JSInvokable]
    public async Task CalendarEventDeleted(string identifier)
    {
        var calendarEvent = Events.FirstOrDefault(x => x.Identifier == identifier);

        if (calendarEvent != null)
            calendarEvent.Status = CalendarEventStatus.Deleted;

        await EventsChanged.InvokeAsync(Events);
    }

    [JSInvokable]
    public Task SetDefaultView(string defaultView)
    {
        View = defaultView ?? CalendarView.ListWeek;

        return Task.CompletedTask;
    }

}

互操作.js

    FullCalendarInterop = (() => {
        return {
            //main function to initiate the module
            init: function (options, dotNetReference) {
                var calendarEl = document.getElementById(options.id);
                var calendar = new window.FullCalendar.Calendar(calendarEl, {
                    plugins: ['interaction', 'dayGrid', 'timeGrid', 'list'],
    
                    isRTL: window.KTUtil.isRTL(),
                    header: {
                        left: 'prev,next today',
                        center: 'title',
                        right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
                    },
    
                    height: 800,
                    contentHeight: 750,
                    aspectRatio: 3,  // see: https://fullcalendar.io/docs/aspectRatio
    
                    views: {
                        dayGridMonth: { buttonText: 'month' },
                        timeGridWeek: { buttonText: 'week' },
                        timeGridDay: { buttonText: 'day' },
                        listWeek: { buttonText: 'list' }
                    },
    
                    defaultView: options.defaultView,
                    defaultDate: options.defaultDate,
    
                    editable: true,
                    eventLimit: true, // allow "more" link when too many events
                    navLinks: true,
                    events: options.calendarEvents,
    
                    eventRender: function (info) {
                        var event = $(info.event);
                        var element = $(info.el);
                        var view = $(info.view);
    
                        if (info.event.extendedProps && info.event.extendedProps.description) {
                            if (element.hasClass('fc-day-grid-event')) {
                                element.data('content', info.event.extendedProps.description);
                                element.data('placement', 'top');
                                window.KTApp.initPopover(element);
                            } else if (element.hasClass('fc-time-grid-event')) {
                                element.find('.fc-title').append('<div class="fc-description">' + info.event.extendedProps.description + '</div>');
                            } else if (element.find('.fc-list-item-title').lenght !== 0) {
                                element.find('.fc-list-item-title').append('<div class="fc-description">' + info.event.extendedProps.description + '</div>');
                            }
                        }
    
                        element.find(".fc-bg").css("pointer-events", "none");
                        element.find(".fc-list-item-title.fc-widget-content").prepend(
                            "<span style='position: absolute; right: 5px;'>" +
                            "<button class='btn btn-icon btn-xs btn-circle btn-light' " +
                            "style='height: 16px; width: 16px;' id='calendar_del_" + event.id + "'>" +
                            "<i class='icon-xs text-dark-50 flaticon2-cross'></i></button></span>");
                        element.find(".fc-content").append("<span style='position: absolute; top: 5px; right: 5px;'>" +
                            "<button class='btn btn-icon btn-xs btn-circle btn-light' " +
                            "style='height: 16px; width: 16px;' id='calendar_del_" + event.id + "'>" +
                            "<i class='icon-xs text-dark-50 flaticon2-cross'></i></button></span>");
                        element.find("#calendar_del_" + event.id).click(function () {
                            var eventId = event[0]._def.defId;
                            var eventIdentifier = event[0]._def.extendedProps.identifier;
    
                            //Remove popover
                            removeContent(".popover.fade.show.bs-popover-top");
                            //$(".popover.fade.show.bs-popover-top").remove();
    
                            dotNetReference.invokeMethodAsync('CalendarEventDeleted', eventIdentifier);
                            //$("#candidate_calendar").fullCalendar('removeEvents', eventId);
                        });
                    },
                    viewSkeletonRender: function(info) {
                        var view = $(info.view);
                        var defaultView = view[0].type !== null ? view[0].type : "";
    
                        dotNetReference.invokeMethodAsync('SetDefaultView', defaultView);
                        //alert(defaultView);
                    }
                });
    
                calendar.render();
            }
        };
    })();

function removeContent(target) {
    $(target).html("");
}

这就是我们在页面中实现它的方式。

页面.razor

@inject IJSRuntime JS

<EditForm Model="@_calendarEvents">
    <div class="card card-custom">
        <div class="card-header">
            <div class="card-title">
                <h3 class="card-label">
                    Calendar
                </h3>
            </div>
            <div class="card-toolbar">
                <a href="#" class="btn btn-light-primary font-weight-bold">
                    <i class="ki ki-plus "></i> Add Event
                </a>
            </div>
        </div>
        <div class="card-body">
            <InputCalendar Id="candidate_calendar" @bind-Events="_calendarEvents"></InputCalendar>
        </div>
    </div>
</EditForm>


@code {

    private List<CalendarEvent> _calendarEvents;

    protected override async Task OnInitializedAsync()
    {
        _calendarEvents =new List<CalendarEvent>
        {
            new CalendarEvent
            {
                Identifier = Guid.NewGuid().ToString(),
                Title = "Breakfast",
                Description = "Time to eat.",
                Start = DateTime.Now.AddHours(6),
                End = DateTime.Now.AddHours(7),
                SolidColor = CalendarEventSolidColor.Primary,
                DotColor = CalendarEventDotColor.Light,
                Status = CalendarEventStatus.Active
            },
            new CalendarEvent
            {
                Identifier = Guid.NewGuid().ToString(),
                Title = "Lunch",
                Description = "Time to eat.",
                Start = DateTime.Now.AddHours(10),
                End = DateTime.Now.AddHours(11),
                SolidColor = CalendarEventSolidColor.Warning,
                DotColor = CalendarEventDotColor.Light,
                Status = CalendarEventStatus.Active
            }
        };

        await base.OnInitializedAsync();
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        // If the calendar changes, we make an action here.

        await base.OnAfterRenderAsync(firstRender);
    }

}
于 2022-01-27T08:50:29.373 回答