Не удается создать магистральный вид

#javascript #backbone.js #requirejs

#javascript #backbone.js #требуется js

Вопрос:

Я постоянно получаю index.js:7 Uncaught TypeError: Cannot read property 'View' of null , что указывает на то, что Backbone не загружен / присутствует, однако, когда я просматриваю загруженные ресурсы на странице backbone-min.js присутствует.

Поскольку ошибок 404 нет, я полагаю, что проблема в самом скрипте. Кто-нибудь видит какие-либо проблемы со скриптом ниже?

ПРИМЕЧАНИЕ: Для удобства я загрузил свой код сюда. ZIP-файл содержит все соответствующие js-файлы. Если вы прокрутите страницу вниз, вы должны увидеть кнопку «медленная загрузка», как только вы нажмете на нее, вам будет предложено ввести код captcha. После ввода кода фактическая кнопка загрузки (под кнопкой «медленная загрузка») появится в течение нескольких секунд.

Просмотр: index.js

 define([
        "jQuery",
        "Underscore",
        "Backbone"
        // I've tried using the modules above as well as direct loading using order! as seen in the following lines.
        //"order!libs/jquery/jquery-min",
        //"order!libs/underscore/underscore-min",
        //"order!libs/backbone/backbone-min",
        ], 
        function($, _, Backbone){
            console.log(_) // prints "undefined"
            console.log(Backbone) // prints Object
            var IndexView = Backbone.View.extend({ // At this line I now get: Uncaught TypeError: Cannot call method 'extend' of undefined
                render: function(){
                    $(this.el).html("<h1>Welcome Dan!</h1>");
                    $("body").html(this.el);
                }
            });
            return new IndexView();
        });
  

Комментарии:

1. по какой-то причине при загрузке backbone в вашем примере подчеркивание еще не помещено в область видимости. Я предполагаю, что вы взяли свой пример из here . Их чрезвычайно похожий, но работает последовательно. Я пока не могу точно понять, почему.

Ответ №1:

Итак, ключом к этой проблеме являются изменения в underscore.js . В частности, тот факт, что теперь он поддерживает AMD (определение асинхронного модуля). Тот факт, что подчеркивание больше не присоединяется к глобальному пространству имен при обнаружении require, нарушает схему, используемую для обеспечения стандартного асинхронного синтаксиса require, но при этом поддерживает синхронную загрузку.

Теперь, когда jQuery, Underscore amp; Backbone (0.5.3 не регистрируется самостоятельно, вам нужно это) поддерживают асинхронную загрузку, вы можете отказаться от этих взломанных библиотек в пользу стандартных и потребовать имена, с которыми эти библиотеки регистрируются. Вот так:

Main.js

 require.config({
    baseUrl: "js",
    paths: { 
               jquery: "libs/jquery/jquery",
               underscore: "libs/underscore/underscore",
               backbone: "libs/backbone/backbone"
           },
    waitSeconds: 10
});

require([
        "app"
        ],
        function(App){
            App.initialize();
            console.log("Main initialized...");
        });
  

index.js

 define([
    "jquery",
    "underscore",
    "backbone"
    ], 
    function($, _, Backbone){
        console.log(_);
        console.log(Backbone);
        var IndexView = Backbone.View.extend({
            render: function(){
                var username = getCookie("username");
                var data = {username: username};
                var compiled = _.template("<h1>Welcome <%= username %></h1>", data);
                $(this.el).html(compiled);
                $("#lt-col").html(this.el);
            }
        });
        return new IndexView();
    });
  

Другие определения были изменены, чтобы отразить новые псевдонимы в нижнем регистре.

Извлеките исправленный код здесь

Ответ №2:

Несмотря на то, что Backbone 0.5.3 регистрирует себя как модуль AMD, он ничего не возвращает. (То же самое для подчеркивания) Если вы измените свою строку:

 function($, _, Backbone){
  

Для

 function($){
  

Это сработает. Для решения, более ориентированного на requirejs, создайте модуль для backbone, который выглядит как:

 define(
[
    'order!libraries/underscore',
    'order!libraries/backbone.0.5.3'
],
function () {
    return Backbone;
}
);
  

—ОБНОВЛЕНИЕ — дополнительная информация

 <head>
<title>Index2</title>
<script src="../../scripts/libraries/require.js" type="text/javascript"></script>
<script type="text/javascript"">
require({
baseUrl: 'scripts'
}, [
'order!libraries/jquery',
'order!libraries/underscore',
'order!libraries/backbone.0.5.3'
], function ($) {
console.log(Backbone);
});
</script>
</head> 
  

Комментарии:

1. Я удалил _ и Backbone из списка аргументов функции, но теперь я получаю сообщение об ошибке: Uncaught TypeError: Cannot call method 'extend' of undefined Есть предложения о том, как это решить?

2. ХМ — не уверен, в чем ваша проблема сейчас. Я обновил свой ответ своей тестовой страницей, которая работает для меня (Backbone записывается в консоль и имеет все нужные функции / свойства). Можете ли вы опубликовать больше кода, и я посмотрю

3. Я только что заметил, что у вас есть запятая в конце после 4-й строки. Иногда IE блюет от такого рода вещей