Подтвердить что ты не робот

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')">
4b9b3361

Ответ 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)();
};