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>

Моят viewModel

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: Не може да се обработи обвързване "text: function (){return address }" Съобщение: адресът не е дефиниран

За магазин #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, предоставен на вашето обратно извикване за създаване, е 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