Значения по умолчанию для отсутствующих параметров - PullRequest
0 голосов
/ 14 апреля 2011

Я использую Knockout с шаблонами jQuery и jQuery.Предположим, что у меня есть шаблон, который ожидает объект person

<script type="text/html" id="person_template">
      <tr><td>Forename</td><td><input type="textbox" data-bind="value:FORENAME" /></td></tr>
      <tr><td>Surname</td><td><input type="textbox" data-bind="value: SURNAME"/></td></tr>
</script>

Теперь, если я передам объект только с FORENAME в этот шаблон, я получу ошибку:

SURNAME не определена ошибка

Я попытался создать пользовательскую привязку в Knockout, но ошибка выдается еще до того, как она туда попадет.

Если я заполню эти пустые поля перед передачей объекта в шаблон, я знаю, что все получится, но я бы хотел, чтобы решение было в моем шаблоне, а не в моем javascript.

Кто-нибудь знает метод, который может помочь в подобных ситуациях?

Ответы [ 2 ]

2 голосов
/ 14 апреля 2011

Это немного сложно, потому что вы находитесь в шаблоне. При подготовке шаблона KO обращается к переменной (ну, на самом деле, к нему в jQuery Templates обращается функция, созданная KO).

Один из вариантов - передать свойство в виде строки в пользовательскую привязку и убедиться, что она инициализирована.

Это было бы как:

ko.bindingHandlers.valueWithInit = {
    init: function(element, valueAccessor, allBindingsAccessor, context) {
        var value = valueAccessor();
        if (!context[value]) {
            context[value] = ko.observable();   
        }
        var realValueAccessor = function() {
             return context[value];   
        }

        //call the real value binding
        ko.bindingHandlers.value.init(element, realValueAccessor, allBindingsAccessor, context);
    },
    update: function (element, valueAccessor, allBindingsAccessor, context) {
        var realValueAccessor = function() {
             return context[valueAccessor()];   
        }

        //call the real value binding
         ko.bindingHandlers.value.update(element, realValueAccessor);   
    }
}

Итак, это подтвердит, что у вашего объекта есть поле, а если нет, то создаст новую наблюдаемую для этого поля. Затем он передает его привязке к реальной стоимости.

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

//Another option: rewrite binding after making sure that it is initialized
ko.bindingHandlers.valueWithInit = {
    init: function(element, valueAccessor, allBindingsAccessor, context) {
        var value = valueAccessor();
        if (!context[value]) {
            context[value] = ko.observable();   
        }

        $(element).attr("data-bind", "value: " + value);
        ko.applyBindings(context, element);
    }
}

Оба из них предполагают, что передаваемое вами поле находится вне объекта, который является контекстом вашего шаблона (поэтому оно не будет работать, если вы передадите что-то с глобальной областью действия, например 'viewModel.someProperty').

Вот рабочий образец с обоими вариантами: http://jsfiddle.net/rniemeyer/dFSeB/

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

0 голосов
/ 14 апреля 2011

Вам лучше убедиться, что для объекта, переданного в шаблон, установлены все параметры. Если это не так, вы можете добавить значения по умолчанию, но размещение всей этой логики в шаблоне идет вразрез с шаблоном MVVM. Шаблоны (например, Views в mvc) не должны содержать какой-либо логики IMO.

...