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

Плагин Jock для нокаута без начальных данных/пустой формы

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

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

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

4b9b3361

Ответ 1

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

Что-то вроде этого: http://jsfiddle.net/rniemeyer/WQGVC/

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

//create an observable if it does not exist and populate it with the input 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 value (could be optional)
        data[property](value);

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

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

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

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

Ответ 2

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

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

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

EDIT: пример: не ASP.NET MVC

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

В любом случае любой объект, идущий к представлению, наследуется от класса 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>

В некоторых санаториях, где изменяется только часть модели представления (это если вы делаете обновления 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>

Ответ 3

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

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

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