Межкомпонентная связь с KnockoutJS

Допустим, у вас есть страница обзора продукта со следующими моделями представления:

  • ProductIndexViewModel; модель корневого представления, привязанная ко всей странице
    • ProductListViewModel; виджет для отображения всех товаров
    • ProductRegistrationViewModel; виджет для регистрации новых продуктов

Виджеты загружаются с использованием пользовательских элементов HTML (например, <product-list></product-list> а также <product-registration></product-registration>). Это здорово, потому что мне не нужно помещать какие-либо знания об этих виджетах в мою корневую модель. Однако я также хотел бы обновить список продуктов после того, как пользователь зарегистрировал новый продукт. Короче:

Как отправить сигнал из ProductRegistrationViewModel в ProductListViewModel?

Я уже изучил Knockout Postbox, но это, похоже, не решает проблему. Что если у меня есть несколько списков продуктов, и я хочу обновить только один из них? В идеале я хотел бы реализовать ряд открытых методов в модели представления моего компонента. Затем свяжите их вместе из модели корневого представления моей страницы, например так:

var ProductIndexViewModel = function() 
{
    var productRegistrationComponent = ??;
    var productListComponent = ??;

    productRegistrationComponent.onRegistrationComplete(function() {
      productListComponent.refresh();
    };
}

Однако у меня нет доступа к этим моделям представления отсюда. Или я?

Как я могу получить доступ к дочерним моделям представления из моей модели корневого представления?

Наконец, если кто-нибудь увидит лучшее решение моей проблемы: я весь в ушах!

2 ответа

Похоже, они должны делиться наблюдаемым массивом (список продуктов). Я думаю, что было бы лучше определить этот список в корневой модели и передать его виджетам, которые зависят от него. Если оба компонента совместно используют одну и ту же наблюдаемую информацию, вам не нужно беспокоиться о связи между этими двумя компонентами. Ваш HTML может выглядеть примерно так: <product-list data-bind="list: $root.allProducts"></product-list>,

Как я могу получить доступ к дочерним моделям представления из моей модели корневого представления?

Если вы хотите, вы могли бы использовать ko.contextFor чтобы получить контекст для элемента HTML.

Я только недавно сделал такого рода вещи. В моем подходе мой компонент создает объект API, который назначается наблюдаемой, которая передается родительским компонентом. Например, у меня есть таблица данных, обернутая компонентом, который я бы хотел найти в выбранных строках:

pageModel = function() {
  this.dtAPI = ko.observable();
}

ko.applyBindigns(new pageModel());
<datatable params="api: dtAPI, data: getTableData()"></datatable>

Внутри компонента вы должны установить наблюдаемую ссылку на API для вашего компонента, чтобы другие могли вызывать его вызовы. В моем случае, я не совсем делаю этот случай, я выставляю API для привязки данных, чтобы позже я мог манипулировать элементом привязки данных (в данном случае это связывание с данными:

if (binding.api != null)
{
    // expose datatable API to context's api binding.
    binding.api({
        getSelectedData: function() { return _getSelectedData(element);}
    });
}

Затем в основном (родительском) компоненте вы можете сделать что-то вроде:

dtAPI.getSelectedData();

До сих пор я нашел этот шаблон как способ показать поведение из внутреннего компонента полезным.

Другие вопросы по тегам