Knockout JS mapping плагин без начальных данных / пустой формы - PullRequest
18 голосов
/ 18 июля 2011

Мы используем knockout и плагин для отображения нокаута, чтобы упростить привязку данных в нашем веб-приложении jQTouch. Причина, по которой мы используем подключаемый модуль отображения, заключается в том, чтобы иметь возможность использовать нокаут без необходимости определять / изменять видовые модели вручную в javascript. Плагин сопоставления отлично работает, когда у вас есть первоначальная загрузка данных из базы данных сервера / клиента.

Проблема, с которой мы сталкиваемся, состоит в том, что у нас есть несколько экранов / представлений, которые имеют форму, в которой возможно, что нет никаких исходных данных. Без этих начальных данных подключаемый модуль сопоставления не может «генерировать» модель представления (ko.mapping.fromJS). Это означает, что нам все еще нужно определить наши модели представления вручную для большей части наших представлений.

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

Ответы [ 3 ]

19 голосов
/ 18 июля 2011

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

Примерно так: http://jsfiddle.net/rniemeyer/WQGVC/

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

//create an observable if it does not exist and populate it with the input's value
ko.bindingHandlers.valueWithInit = {
    init: function(element, valueAccessor, allBindingsAccessor, data) {
        var property = valueAccessor(),
            value = element.value;

        //create the observable, if it doesn't exist 
        if (!ko.isWriteableObservable(data[property])) {
            data[property] = ko.observable();
        }

        //populate the observable with the element's value (could be optional)
        data[property](value);

        ko.applyBindingsToNode(element, { value: data[property] });
    }
}

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

<input data-bind="valueWithInit: 'name'" />

Пример здесь: http://jsfiddle.net/rniemeyer/JPYLp/

4 голосов
/ 20 июля 2011

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

То, как я обычно работаю с нокаутом, никогда не заканчивается отправкой пустого представлениямодель на вид.Модель представления обычно имеет все поля, к которым я привязываю.Хотя они могут быть пустыми строками или инициализированными объектами без отображаемых значений, фактические объекты по-прежнему завершаются с правильным представлением каждого объекта в полях, к которым я привязан.

Возможно, вы захотите просто посмотретьотправка пустых объектов вместо ничего в представление.

РЕДАКТИРОВАТЬ: Пример un ASP.NET MVC

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

В любом случае, любой объект, идущий в представление, наследуется от класса vmBaseкоторый в основном предоставляет метод toJSON (), который генерирует сериализацию объекта JSON.На мой взгляд, это вызывается механизмом просмотра.Как показано в коде ниже.

      <script type='text/javascript'>         
        var viewModel = ko.mapping.fromJS(<%= Model.ToJson() %>);                     

        $(document).ready( function () {        
            ko.applyBindings(viewModel);                             
        });                  
     </script>   

Когда я готов отправить код обратно, я просто удаляю версию JS модели представления.

<script type='text/javascript'>
     var dataToSendToServer = ko.toJS(viewModel);
</script>

В некоторых sanarios, где меняется только часть модели представления (это если вы выполняете обновления AJAX), вы можете делать некоторые интересные вещи, такие как переключение шаблонов, чтобы можно было использовать различные привязки.применены.В этом случае мы используем # ID_of_Container в качестве контейнера исходных данных / шаблона и заменяем шаблон (который может содержать элементы data-bind = "") новым шаблоном ID_of_Template

<script type='text/javascript'>
    ko.cleanNode($("#ID_of_Container"));
    delete (viewModel.Some_Element_To_Be_Updated);
    viewModel = ko.mapping.updateFromJS(viewModel, New_Data_For_That_Element);

    // Use ko.toJS(viewModel) because standard template plugin doesn't understand 
    // knockout observables
    $("#ID_of_Container").html($("#ID_of_Template").tmpl(ko.toJS(viewModel)))
    ko.applyBindings(viewModel, $("#ID_of_Container")[0]);

</script>
0 голосов
/ 01 марта 2013

Один из подходов, который я сейчас изучаю, заключается в создании дополнительного метода веб-службы с именем ReturnEmptyObject (), который не делает ничего, кроме создания и возврата нового экземпляра объекта (свойства которого будут значениями по умолчанию) на стороне сервера. Объект (в моем случае C #) сериализуется в JSON и, наконец, поступает при вызове jQuery Ajax .... и затем передается в ko.mapping.updateFromJS () ..., который создает необходимые наблюдаемые при начальной загрузке страницы. прежде чем я вызову ko.applyBindings ().

Когда ko.applyBindings () выполняется, он находит наблюдаемые данные, которые ему нужны, чтобы не выдавать ошибку, даже если они в основном пусты.

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

...