0

我有仅代码组件,我在其中生成我的菜单,在那里我得到了大约 700 条记录,所有这些记录都被一次加载。我决定重新创建它并在单击事件时将另一个菜单对象加载到菜单。

这是我的菜单视图模型,我从视图模型中删除了一些不相关的部分

public class CategoryMenuViewModel : DotvvmViewModelBase
{
    public static CategoryMenuFacade MenuFacade { get; private set; }

    public static List<CategoryMenuDTO> CategoryMenuList { get; set; } = new List<CategoryMenuDTO>();
    //private static bool LoadMoreCategories { get; set; }

    public CategoryMenuViewModel(CategoryMenuFacade categoryMenuFacade)
    {
        MenuFacade = categoryMenuFacade;
    }

    public override Task PreRender()
    {
        if (!Context.IsPostBack)
        {
            CategoryMenuList.AddRange(CategoryMenuFacade.GetCategoryMenu(CategoryId));
            //CategoryMenuList = MenuFacade.GetCategoryMenu();
        }

        return base.PreRender();
    }

    public static int? CategoryId { get; set; }
    public static List<int> PreviousCategoryId { get; set; } = new List<int>();

    [AllowStaticCommand]
    public static List<CategoryMenuDTO> SelectedCategory()
    {

        if (CategoryId == null) return CategoryMenuList;
        bool idExist = PreviousCategoryId.Any(r => r == CategoryId);
        if (!idExist)
        {
            PreviousCategoryId.Add((int)CategoryId);
            CategoryMenuList.AddRange(MenuFacade.GetCategoryMenu(CategoryId));
        }
        return CategoryMenuList;
    }
}

我之前的想法是,我可以使用此脚本加载菜单的另一部分,在其中获取我单击的对象 ID 并将其发送到 viewmodel。它工作正常,但这种方法的问题是,它会触发PreRender()方法并再次从另一个视图模型加载所有数据。

dotvvm.events.beforePostback.subscribe(function (data) {
try {
    var selectedCategory = $(event.target.lastChild);
    var nodeId = selectedCategory[0].attributes.Id.nodeValue;
    var idNumber = nodeId.substring(nodeId.indexOf("_") + 1);
    data.viewModel.CategoryMenuViewModel().CategoryId = idNumber;

} catch (error) {
    // continue with error
}});

我的另一个想法是使用knockout binding handler我可以CategoryId在 viewModel 中更新我的属性的位置,但我不确切知道如何在 viewModel 中触发我的某些方法,甚至code-only-component渲染新数据。

ko.bindingHandlers["click"] = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
    $(element)
        .on('click', function (e) {
            var selectedCategory = $(e.target.lastChild);
            var nodeId = selectedCategory[0].attributes.Id.nodeValue;
            var idNumber = parseInt(nodeId.substring(nodeId.indexOf("_") + 1));
            //data.viewModel.CategoryMenuViewModel().CategoryId = idNumber;
            // if someone deletes the value from the textbox, set null to the viewmodel property
            var prop = valueAccessor();

            if (ko.isObservable(prop.CategoryItemId)) {
                prop.CategoryId(idNumber);
            }

        });
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
    // get the value from the viewmodel
    var value = ko.unwrap(valueAccessor());
    var test = viewModel.CategoryId();
}};

这是我的看法

<cc:CategoryMenu DataContext="{{value: CategoryMenuViewModel}}" class="categorieMenu" ID="mainMenu"/>

.dotcontrol归档

<coc:CategoryMenu DataSource="{{value: CategoryMenuViewModel.CategoryMenuList}}"
                  ActiveCategory="{{controlProperty: ActiveCategory}}"
                  SelectedValue="{{value: CategoryMenuViewModel.CategoryId}}"
                  ItemValueBinding="{{value:Id}}"
                  data-bind="click: {CategoryId}"
                  Click="{{staticCommand: CategoryMenuViewModel.SelectedCategory()}}"/>

我的属性的简短预览coc

    public static readonly DotvvmProperty ChangedProperty
        = DotvvmProperty.Register<Command, CategoryMenu>(c => c.Changed, null);
    public Command Changed
    {
        get => GetValue(ChangedProperty) as Command;
        set => SetValue(ChangedProperty, value);
    }
    public int SelectedItemId
    {
        get => (int)GetValue(SelectedItemIdProperty);
        set => SetValue(SelectedItemIdProperty, value);
    }
    public static readonly DotvvmProperty SelectedItemIdProperty
        = DotvvmProperty.Register<int, CategoryMenu>(c => c.SelectedItemId);

所以我的问题是,如何处理更改的事件以触发方法,该方法将加载菜单的另一部分并使用我的组件呈现它?

4

0 回答 0