Связывание можно наблюдать с помощью Knockout в приложении Hot Towel

Я только начал новый проект Hot Towel SPA, и у меня возникли проблемы с привязкой к нокауту из ViewModel.

Моя модель зрения выглядит так:

define([
    "services/logger",
    "knockout"
],
function (logger, ko) {
    var title = ko.observable("Partners");


    return {
        title: title,
        activate: function () {
            var that = this;
            logger.log("Partners view activated", null, "admin.partners", false);

            return true;
        }
    };
});

Вид выглядит так:

<section class="row-fluid">
    <div class="span10" id="admin-content">
        <h2 class="page-title" data-bind="text: title"></h2>
    </div>
</section>

Но заголовок всегда оказывается мусором (т.е. кодом функции, как при использовании отладчика: FUNCTION D(){IF(0

Если я изменяю привязку на "data-bind="text: title()", это работает, но я понял, что это не связывает наблюдаемое, только значение. Так что при выполнении форм с такими привязками это не так. Я не могу обновить наблюдаемое, и я не могу сохранить значение.

Я нашел примеры, которые, кажется, используют тот же код, что и я, но я не понимаю, почему он не работает.

3 ответа

Решение

Кристиан - Вы сами это поняли. Я уточню.

Посмотрите на комплект поставщика, определенный в App_Start/bundleconfig.cs, а затем посмотрите на загрузку скрипта в нижней части index.cshtml (~ строка 29).

Вы увидите, что все сторонние скрипты - включая скрипт нокаута - загружаются вместе... перед Require. Это означает, что ни один из сторонних сценариев не может обнаружить предстоящее использование require. Поэтому они загружаются в глобальное пространство имен (окно).

Когда появляется RequireJS, он также не знает ни об одной из этих служб. Поэтому, когда вы запрашиваете "ко" в качестве зависимости, он возвращает null... как вы сами видите, поставили ли вы точку останова, где начинается ваша функция.

Все это по замыслу.

Вы можете добавить эти сервисы в эквивалент require IoC контейнера. Если вы это сделаете, require найдет 'ko', и ваша функция будет работать. Вы можете начать узнавать об этом здесь. Я сделал это. Это не так уж плохо.

Но некоторые из нас, кто какое-то время плавал в этих водах, решили, что это слишком много для PITA. Поэтому мы следуем упрощенной рекомендации Durandal: " Загрузите несколько сторонних библиотек вне Require и позвольте им засорять глобальное пространство имен; ваши более многочисленные файлы приложений должны находиться в Require ".

Это не так сложно выбрать иначе. Просто научитесь подгонять требовать в вашем main.js, и вы будете в бизнесе.

Проблема была найдена с помощью разработчика Durandal здесь: https://groups.google.com/forum/

Похоже, что использование AMD для включения нокаута было проблемой. Я не знаю специфики, но, вероятно, это как-то связано с тем, что Durandal использует глобальную переменную ko, в то время как мои модели представлений использовали переменную ko, которая была другой, потому что RequireJS создал свой собственный экземпляр.

Можете ли вы попробовать что-то вроде этого:

define([
    "services/logger",
    "knockout"
],
function (logger, ko) {
    var title = "Partners";


    return {
        title: ko.observable(title),
        activate: function () {
            var that = this;
            logger.log("Partners view activated", null, "admin.partners", false);

            return true;
        }
    };
});
Другие вопросы по тегам