メニューを生成するコードのみのコンポーネントがあり、約 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 を取得してビューモデルに送信できると考えていました。正常に動作しますが、このアプローチの問題は、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
}});
私の他の考えは、viewModel でknockout binding handler
自分のプロパティを更新できる場所を使用することCategoryId
でしたが、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);
だから私の質問は、変更されたイベントを処理して、メニューの別の部分をロードし、コンポーネントを使用してレンダリングするメソッドを起動するにはどうすればよいですか?