Knockoutjs: можно ли создать зависимую функцию Observable с параметром?
У меня есть несколько ящиков ввода, которые я хочу скрыть/показать на основе выбора пользователя.
Я могу добиться этого, имея отдельный зависимый доступ к каждому входу и, в свою очередь, делая зависимый доступным для наблюдения за родительским выбором.
viewModel.showField1= ko.dependentObservable(function () {
return viewModel.selectedType() ? IsFeatureVisible(viewModel, "BusinessFieldName1") : false;
}, viewModel
);
viewModel.showField1= ko.dependentObservable(function () {
return viewModel.selectedType() ? IsFeatureVisible(viewModel, "BusinessFieldName2") : false;
}, viewModel
);
Это довольно утомительно для каждого поля. Могу ли я привязывать элементы с помощью функции dependObservable, которая может принимать параметр? Важно то, что он должен срабатывать, когда родитель меняет
Другой вариант заключается в том, что когда родитель меняет, я просматриваю элементы и скрываю/скрываю, но для этого потребуется сопоставить имя элемента id ↔ имя поля.
Current
<tr data-bind="visible: showField1">
<tr data-bind="visible: showField2">
Желаемый
<tr data-bind="visible: showField('BusinessFieldName1')">
<tr data-bind="visible: showField('BusinessFieldName2')">
Ответы
Ответ 1
В Knockout привязки реализуются внутренне с использованием dependObservables, так что вы можете фактически использовать обычную функцию вместо dependObervable в ваших привязках. Связывание будет выполнять вашу функцию внутри зависимого объекта, так что любые наблюдаемые, которые имеют доступ к их значению, будут создавать зависимость (ваша привязка снова загорится, когда она изменится).
Вот пример: http://jsfiddle.net/rniemeyer/2pB9Y/
HTML
type "one", "two", or "three": <input data-bind="value: text" />
<hr />
<ul data-bind="template: { name: 'itemTmpl', foreach: items }"></ul>
JS
<script id="itemTmpl" type="text/html">
<li data-bind="text: name, visible: viewModel.shouldThisBeVisible(name)"></li>
</script>
var viewModel = {
text: ko.observable("one"),
items: [{name: "one"}, {name: "two"}, {name: "three"}],
};
viewModel.shouldThisBeVisible = function(name) {
return this.text() === name;
}.bind(viewModel);
ko.applyBindings(viewModel);
Ответ 2
var someOtherViewModel = {
showField: function(fieldName) {
return ko.dependentObservable(function () {
return viewModel.selectedType() ? IsFeatureVisible(viewModel, fieldName) : false;
}, viewModel);
}
};
Вы можете создать функцию, подобную приведенной выше. Функция возвращает новый зависимый наблюдаемый для конкретного имени поля.
Теперь вы можете сделать:
<tr data-bind="visible: someOtherViewModel.showField('Field1')">
Сообщите мне, если этот код не работает - возможно, я что-то пропустил. Затем я отредактирую этот пост.
Ответ 3
Взяв идею от @Arxisos еще дальше, я придумал это.
self.showField = function (fieldName)
{
return ko.dependentObservable(function ()
{
return this.selectedType() ? IsFeatureVisible(this, fieldName) : false;
}, this)();
};