KnockoutJS: отслеживание кликов по меню - PullRequest
1 голос
/ 13 марта 2011

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

Вот мои шаблоны:

<script id="menuItemTemplate" type="text/html">
    <li class='${ Class }' >
        <a class='${ Class }' data-bind='click: function() { viewModel.menuClicked(Id); }'>${ Name }</a>
        <ul class='${ Class }' data-bind='template: { name: "menuItemTemplate", foreach: Items }'></ul>
    <li>
</script>
<script id="menuTemplate" type="text/html">
    <ul class='${ Class }' data-bind='template: { name: "menuItemTemplate", foreach: Items }'></ul>
</script>
<script id="consoleTemplate" type="text/html">
    <div class='${ Class }' data-bind='template: { name: "menuTemplate", data: Menu }'></div>
</script>
<h2>Application Administration</h2>
<div id="console" class="console" data-bind='template: { name: "consoleTemplate", foreach: Panels }'>
</div>

А вот упрощенный код для моей модели представления:

$(function () {
var viewModel = {
    "Panels": [
        {
        "Id" : 1,
        "Class": "main",
        "Menu": {
            "Id": 1,
            "Class": "file",
            "Name": "File",
            "Items": [{
                "Id": 1,
                "Class": "open",
                "Name": "Open",
                "Items": []
            }]
        }
    }]
};

    $.ajax({
        url: 'console.asmx/Initialize',
        type: "POST",
        cache: false,
        contentType: "application/json; charset=utf-8",
        data: "{}",
        dataType: "json",
        success: function (data) {
            viewModel = data.d;
            viewModel.menuActive = ko.observable(false);
            viewModel.currentMenu = ko.observable(0);
            viewModel.menuClicked = function (id) {
                viewModel.menuActive(true);
                viewModel.currentMenu(id);
            };
            ko.applyBindings(viewModel);
        }
    });
});

Пока что панели и меню отображаются нормально, но теперь мне нужно знать, по какому меню щелкнули, и показать подменю, а также другие элементы пользовательского интерфейса на основе этого меню.Функция, которую я прикрепил к гиперссылкам, вызывает исключение: 'Uncaught ReferenceError: viewModel is not defined' когда я нажимаю на любую из гиперссылок.

Я также пытался привязать видимость подменю к свойству "currentMenu" viewModelно это сломало все:

<script id="menuItemTemplate" type="text/html">
    <li class='${ Class }' data-bind='visible: viewModel.menuActive && viewModel.currentMenu == Id'>
        <a class='${ Class }' data-bind='click: function() { viewModel.menuClicked(Id); }'>${ Name }</a>
        <ul class='${ Class }' data-bind='template: { name: "menuItemTemplate", foreach: Items }'></ul>
    <li>
</script>

Как я могу правильно связать обработчик события щелчка, а также видимость, основанную на нажатом меню?

1 Ответ

4 голосов
/ 13 марта 2011

Ваша проблема в том, что ваша переменная viewModel определена в функции готовности jQuery, поэтому функции в ваших привязках данных не могут ее видеть, поскольку она не находится в глобальной области видимости. Даже var viewModel = {} вне $(function() { ... }); будет работать.

То, как вы определили свою функцию щелчка, мне нравится. Однако ваша видимая логика должна использовать viewModel.menuActive() и viewModel.currentMenu() для доступа к значениям в том виде, как они есть в выражении.

Надеюсь, это поможет. Будем рады помочь в дальнейшем, если вы застряли.

...