привязка наблюдаемых массивов к нескольким элементам <ul>

0

Для меню навигации у меня есть две группы ссылок, каждая группа и ссылка отображаются или не зависят от роли пользователя. Роли просматриваются при построении структуры ссылок и построении списка ссылок. Возвращенный JSON получает синтаксический анализ, помещает в наблюдаемые массивы без проблем, но когда я на самом деле пытаюсь применить привязки, привязка не выполняется, потому что наблюдаемые пустые. Вот HTML...

<ul id="user-menu" class="menu" data-bind="foreach: areas">
    <li>
        <a data-bind="attr: { href: areaLink }">
            <img data-bind="attr: { src: iconUri }" />
            <span data-bind="text: areaName"></span>
        </a>
    </li>
</ul>
<ul id="admin-menu" class="menu" data-bind="foreach: adminAreas">
    <li>
        <a data-bind="attr: { href: areaLink }">
            <img data-bind="attr: { src: iconUri }" />
            <span data-bind="text: areaName"></span>
        </a>
    </li>
</ul>

Модель нокаута в фоновом режиме...

var navigation = (function() {

    function Area() {
        var self = this;

        self.areaName = ko.observable();
        self.areaLink = ko.observable();
        self.iconUri = ko.observable();
        self.sequenceNo = ko.observable();
        self.isAdmin = ko.observable();

        self.loadFromVM = function (vm) {
            self.areaName(vm.name || '');
            self.areaLink(vm.link || '');
            self.iconUri(vm.iconUri || '');
            self.sequenceNo(vm.sequenceNo || '');
            self.isAdmin(vm.isAdmin);
        }
    }

    function viewModel() {
        var self = this;

        self.areas = ko.observableArray([]);
        self.adminAreas = ko.observableArray([]);

        self.setup = function () {
            var data = {}; // population with basic session data

            $.getJSON('....php', { JSON.stringify(data) }, function (results) {
                for (var i = 0; i < results.length; i++) {
                    var area = new Area();

                    area.loadFromVM(results[i]);

                    if (area.isAdmin()) {
                        self.adminAreas().push(area);
                    } else {
                        self.areas().push(area);
                    }
                }
            });
        };
    }

    var vmInstance;

    return {
        setup: function () {
            vmInstance = new viewModel();

            vmInstance.setup();

            ko.applyBindings(vmInstance, $('#user-menu')[0]);
            ko.applyBindings(vmInstance, $('#admin-menu')[0]);
        }
    };

})();

И затем я привожу его вместе с этим в файле вида навигации...

    navigation.setup();

Поэтому после того, как я верну свой JSON, проанализирую его и организую, когда я прохожу через функцию успеха метода $.getJSON, ставя часы на self.areas() и self.adminAreas(), показывает, что массивы имеют точную информацию я хочу, чтобы они. Но к моменту их применения нужно называть vmInstance.areas().length vmInstance.adminAreas().length или vmInstance.adminAreas().length возвращает ноль. Еще более странно, добавляя предупреждение с длиной массивов сразу после вызова $.getJSON но внутри функции setup() вызывает предупреждение сначала, показывает нули, затем проходит через get, заполняет массив, затем снова обнуляет нули.

Не совсем уверен, что происходит здесь, но я не помню, как такое поведение наблюдалось в другом проекте, поэтому я не совсем уверен, что я здесь делаю неправильно. Любые идеи или советы были бы весьма признательны.

EDIT: Nevermind на скрипке. Это действительно не отражает мою фактическую ошибку.

  • 0
    код действителен, поэтому я думаю, что это проблема ajax-вызова, потому что, поскольку это асинхронный вызов, прежде чем ответ станет доступным, выполняется привязка. попробуй отладить в firebug.
  • 0
    Это возможно, но у меня был такой же код, который отлично работал в других проектах. Привязки должны обновляться по мере поступления асинхронного вызова, и я вижу, что это происходит в Chrome Developer Tools.
Показать ещё 3 комментария
Теги:
knockout.js

1 ответ

0

Объект adminarea не инициализирован. Вы внесли переменную adminArea, но вместо этого вы использовали ту же переменную области для установки значений.

    var adminArea = new Area();

    adminArea.areaName('test admin area'); 
    adminArea.areaLink('#');
    adminArea.iconUri('http://evernote.com/media/img/getting_started/skitch/windows8/win8-checkmark_icon.png');
    adminArea.sequenceNo(1);
    adminArea.isAdmin(true); 

Демо-версия скрипта

  • 0
    и вам не нужно вызывать applyBinding дважды. ko.applyBindings (vm) сделает все, что вам нужно.
  • 0
    Да. спасибо за исправление :) я обновил скрипку.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню