Отображение Knockoutjs и неструктурированные данные

Как использовать неструктурированные данные с помощью плагина для отображения Knockoutjs? Например исходный json:

[
    {
        "id": 1,
        "name": "Store #1",
        "address": "City #1"
    },
    {
        "id": 2,
        "name": "Store #2"
    }
]

Магазин №2 без адреса. Мой шаблон:

<ul data-bind='foreach: data'>
    <li data-bind='with: id'>
        <a href data-bind='text: name, click: function () { $parent.view($data, $index()) }'>           
        </a>
        <span data-bind='text: address'></span> 
   </li>
</ul>

Мой взглядМодель

Module.store = function () {

    var self = this;

    self.data = ko.mapping.fromJS([]);
    self.init = function () {
        $.getJSON('json/stores.json', function (stores) {
            ko.mapping.fromJS(stores, self.data);
        });
    };
};

Если я запускаю этот код, я получаю сообщение об ошибке:

Uncaught ReferenceError: невозможно обработать привязку «текст: функция () {адрес возврата}» Сообщение: адрес не определен

Для магазина №2

Как я могу установить нулевую или пустую строку для свойства адреса магазина № 2?


person Булат Сайфутдинов    schedule 30.11.2014    source источник


Ответы (2)


Если ваше представление показывает адрес, то ваша модель представления должна содержать это свойство.

Создайте модель представления для отдельных магазинов:

Module.Store = function (data) {
    this.id = null;
    this.name = null;
    this.address = null;

    ko.mapping.fromJS(data, {}, this);
}

и определение сопоставления использования (см. документацию). в вашем списке магазинов:

Module.StoreList = function () {
    var self = this,
        mappingDefinition = {
            create: function (options) {
                return new Module.Store(options.data);
            }
        };

    self.stores = ko.observableArray();

    self.viewStore = function (store) {
        // ...
    };
    self.init = function () {
        $.getJSON('json/stores.json', function (stores) {
            ko.mapping.fromJS(stores, mappingDefinition, self.stores);
        });
    };
};

Модифицированное представление (как правило, старайтесь избегать встроенных функций в определении представления):

<ul data-bind='foreach: stores'>
    <li>
        <a href data-bind='text: name, click: $parent.viewStore'></a>
        <span data-bind='text: address'></span> 
    </li>
</ul>
person Tomalak    schedule 30.11.2014
comment
create: function (options) { к чему именно относятся options и options.data . Я пытаюсь понять отображение, есть ли ссылка с более подробным объяснением. нокаутные документы недостаточно полезны - person super cool; 30.11.2014
comment
Вы должны читать внимательнее. Это прямо из документов: < i>Аргумент options, предоставленный вашему обратному вызову create, представляет собой объект JavaScript, содержащий: data: объект JavaScript, содержащий данные для этого дочернего элемента, и parent: родительский объект или массив, к которому принадлежит этот дочерний элемент - person Tomalak; 30.11.2014

Мне не кажется, что knockout-mapping-plugin имеет такую ​​функциональность из коробки. Вероятно, вам следует подумать о том, чтобы попробовать другой обходной путь для этой проблемы, я вижу как минимум два:

1) возврат json с null с сервера

2) отображение этого диапазона условно, например:

<ul data-bind='foreach: data'>
    <li data-bind='with: id'>
        <a href data-bind='text: name, click: function () { $parent.view($data, $index()) }'>           
        </a>
        <!-- ko if: address -->
        <span data-bind='text: address'></span> 
        <!-- /ko -->
   </li>
</ul>
person Vladimirs    schedule 30.11.2014