Knockout.js и нули

Я использую комбинацию Knockout.js + плагин сопоставления Knockout + jQuery в многофункциональном веб-клиенте, который использует JSON из RESTful API. .

Мне нужно руководство о том, как работать с нулевыми значениями в моей модели представления. Вот мой сценарий и проблема, с которой я столкнулся:

Большинство членов данных, возвращаемых REST API, обнуляются. Чтобы учесть это, я передаю плагину сопоставления образец JSON с нулевыми значениями:

um.jsonMaps.campaign = {
    "priority": null,
    "recipientListId": null,
    "autoPrepare": null,
    "timeToSend": null
}

Я делаю начальную привязку следующим образом:

this.model = ko.mapping.fromJS(um.jsonMaps.campaign);

Вот некоторые данные из вызова API:

var data= {
    "priority": 95,
    "recipientListId": "a2aac72a-59f6-45da-a636-a48cc2b20137",
    "autoPrepare": false,
    "timeToSend": null
}

... который связан следующим образом:

ko.mapping.fromJS(data, this.viewModel.model);

Проблема заключается в том, что если пользователи изменяют или касаются любого из элементов пользовательского интерфейса, привязанных к этим данным, они неявно превращают член данных в модели в строковый литерал в кавычках. Таким образом, целое число 95 становится "95", если пользователь добавляет текст и удаляет его. И если в пользовательском интерфейсе коснуться значения, которое было пустым из API, оно становится "" (например, пустой строкой).

Мне нужно, чтобы целые числа и нули оставались целыми и нулевыми после редактирования.


person Armchair Bronco    schedule 14.06.2012    source источник
comment
Если вы хотите продолжать использовать подключаемый модуль сопоставления и не хотите предоставлять расширенные параметры сопоставления, вы можете использовать пользовательскую привязку, которая обертывает привязку значения, как описано в этом ответе: stackoverflow.com/questions/7395946/.   -  person RP Niemeyer    schedule 15.06.2012
comment
Это еще одна хорошая ссылка. Сейчас просматриваю информацию.   -  person Armchair Bronco    schedule 15.06.2012
comment
Я просмотрел эту информацию, но понял, что пользовательская привязка создает уровень сложности, который мне на самом деле не нужен. Ответ, который я в конечном итоге принял, помог мне, позволив мне продолжить использовать собственные привязки текста и значений. Как для пользовательской привязки, так и для KO.computed observables мне все равно пришлось написать нетривиальный объем кода, потому что наш API требует специальной обработки нулевых значений (в строках, числах, датах и ​​даже логических значениях). Использование вычисляемых наблюдаемых фактически привело к меньшему количеству кода для меня.   -  person Armchair Bronco    schedule 16.06.2012


Ответы (2)


В моем проекте я закончил создание модели представления по данным с сервера. Я добавил новое свойство с помощью геттера и сеттера, чтобы при необходимости оно записывало числовое значение:

function DataViewModel(dataModel) {
    var self = this;
    self.priority = ko.observable(dataModel.priority);
    self.recipientListId = ko.observable(dataModel.recipientListId);
    self.autoPrepare = ko.observable(dataModel.autoPrepare);
    self.timeToSend = ko.observable(dataModel.timeToSend);



    self.priorityKo = ko.computed({
        read: function () {
            return self.priority().toFixed(2);
        },
        write: function (value) {
            value = parseFloat(value.replace(/[^\.\d]/g, ""));
            if (isNaN(value)) {
                self.priority(-1); // to fire 'changed' event
                self.priority(0); // final value in case of incorrect user input
            } else {
                self.priority(value); // real numeric value
            }
        },
        owner: this
    });

ваше отображение будет выглядеть так:

this.model = ko.mapping.fromJS(new DataViewModel(um.jsonMaps.campaign));
person Pavel Morshenyuk    schedule 14.06.2012
comment
Хорошо, похоже, это может сработать. Это означает, что мне придется отказаться от использования подключаемого модуля сопоставления, но мне нравится возможность точной настройки различных элементов вычисляемых данных. А для нулевых значений, которые преобразуются в пустые строки (это то, что в настоящее время убивает меня, когда я вызываю наш API обновления), я снова превращаю эти значения в нулевые. - person Armchair Bronco; 15.06.2012
comment
Я проверю, работает ли это для меня завтра, и если да, то приму этот ответ. Спасибо! - person Armchair Bronco; 15.06.2012
comment
нет проблем, в моем проекте я также реализовал метод создания объекта сервера из модели представления (чтобы отправить его на сервер), но я думаю, что это можно заархивировать с помощью плагина сопоставления - person Pavel Morshenyuk; 15.06.2012
comment
Правильно. Я имел в виду, что я должен отказаться от использования подключаемого модуля картографирования в качестве своего рода черного ящика, который просто творит чудеса без какого-либо другого вмешательства с моей стороны — это лучшая часть подключаемого модуля. В идеале плагин должен поддерживать это, когда я передаю начальную модель данных вместе с типом данных, который я хочу использовать: string, bool, int, float или null. - person Armchair Bronco; 15.06.2012
comment
Я принял это как ответ. Я также рассмотрел вариант пользовательской привязки, но для моего варианта использования эта реализация была чище. В итоге я сделал несколько незначительных модификаций (которые трудно передать в этом пользовательском интерфейсе [одно из моих небольших разочарований по поводу модели S.O., которая принимает ответ, но не может показать изменения кода, необходимые для того, чтобы заставить его работать для моего сценария). В моей версии я делаю так: self.priority_KO = ko.observable(dataModel.priority), а затем: self.priority = ko.computed(...) Это означает, что я могу привязываться к приоритету в своей разметке. - person Armchair Bronco; 16.06.2012
comment
Мне также пришлось написать несколько служебных методов, которые возвращают версии JS-объектов модели, в которых удалены все члены *_KO. - person Armchair Bronco; 16.06.2012
comment
так что вы расширяете объекты json сервера свойствами KO, а затем удаляете их перед отправкой обратно на сервер? звучит отлично для меня. Не могли бы вы привести несколько примеров? хочу попробовать на своем проекте :) - person Pavel Morshenyuk; 17.06.2012
comment
Ага, именно этим я и занимаюсь. Я опубликую еще один ответ на этот вопрос с примером кода, показывающим, как я работаю с целыми числами и строками, которые также могут быть нулевыми. Мне понадобится некоторое время, чтобы закончить мой живой код (должен держать Человека подальше от меня!), а затем я помассирую свою реализацию для этой темы. - person Armchair Bronco; 18.06.2012
comment
Что ж, у меня возникают некоторые проблемы с моей реализацией при работе с логическими значениями, которые также могут быть нулевыми. Хочу разобраться в этом, прежде чем опубликовать какой-либо код. Извините за задержку. - person Armchair Bronco; 19.06.2012