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" является моделью представления контейнера, в которую вложены два других компонента, вы можете использовать подход в этой скрипке