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

Я использую компоненты выбивки для создания поискового представления с различными частичными представлениями, которые имеют свои собственные модели представления:

  • Поле поиска
  • Фильтр

Итак, модель представления поля поиска выглядит примерно так:

define(["knockout", "text!./search-field.html"], function (ko, templateMarkup) {
    function SearchFieldVM(params) {
        this.query = ko.observable("");
    }

    return { viewModel: SearchFieldVM, template: templateMarkup };
}

и модель представления фильтра выглядит примерно так:

define(["knockout", "text!./filter.html"], function (ko, templateMarkup) {
    function FilterVM(params) {
        this.categories = ko.observableArray();
        this.currentCategory = ko.observable();
    }

    return { viewModel: FilterVM, templateMarkup };
}

У меня есть Поиск VM:

define(["knockout", "text!./search.html"], function(ko, templateMarkup) {
    function SearchVM(params) {
        this.currentQuery = ko.observable();
        this.currentCategory = ko.observable();
    }

    return { viewModel: SearchVM, template: templateMarkup };
}

Хорошо, вот в чем дело. Всякий раз, когда кто-либо меняет запрос, наблюдаемый в SearchFieldVM, я хочу изменить currentQuery, наблюдаемый в Search VM.

То же самое относится и к текущей категории.

Допустим, что мой вид поиска выглядит так:

<search-field></search-field>
<filter></filter>

Как тогда я могу прослушать наблюдаемый запрос компонента поля поиска и отфильтровать текущую категорию компонента, чтобы Search VM заметил эти изменения?

1 ответ

Похоже, вы хотите, чтобы свойство "query" в экземпляре класса "SearchFieldVM" ссылалось на свойство "currentQuery" в экземпляре класса "SearchVM", т.е. когда обновляется "query", тогда "currentQuery" также должен обновляться,

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

define(["knockout", "text!./search-field.html"], function (ko, templateMarkup) {
    function SearchFieldVM(params) {
        this.query = params.refToSomeObservable;
    }

    return { viewModel: SearchFieldVM, template: templateMarkup };
}

define(["knockout", "text!./search.html"], function(ko, templateMarkup) {
    function SearchVM(params) {
        this.currentQuery = params.refToSomeObservable;
        this.currentCategory = ko.observable();
    }

    return { viewModel: SearchVM, template: templateMarkup };
}

Предполагая, что у вас есть какая-то другая модель представления, представляющая представление, которое содержит экземпляры этих компонентов, мы можем создать для него свойство, которое будет представлять эту общую наблюдаемую.

var MyViewModelThatRepresentsSomeContainerOfComponents = {
name: ko.observable("whats your name?")
searchQuery: ko.observable('default query maybe?')

}

Тогда в вашей разметке вы можете сделать это:

<div>
    <input type="text" data-bind="value: name" />
    <search-field params="refToSomeObservable: searchQuery"></search-field>
    <filter></filter>
    <search params="refToSomeObservable: searchQuery"></search>
</div>

В противном случае, если "SearchVM" является моделью представления контейнера, в которую вложены два других компонента, вы можете использовать подход в этой скрипке

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