1

ビュー モジュール (overlay.screen.view.js) が警告時に変数が未定義 (Uncaught TypeError: Cannot call method 'template' of undefined) である必要がある理由がわかりません。パスは正しいように見えますが、明らかに何かがおかしくなっています。私は何を間違えましたか?前もって感謝します。

これが私のディレクトリ構造です:

www
 |-js
   |-app
     consumer.activity.js
     |-views
       overlay.screen.view.js
   |-test
   |-vendor
     |-backbone
     |-fastclick
     |-jquery
     |-sinon
     |-superslides
     |-underscore

私の consumer.activity.js ファイル (基本的には main.js) 内:

require.config({

    baseUrl: '../../js',
    paths: {
        root: '..',
        jquery: 'vendor/jquery/jquery.2.0.3.min'
    },
    shim: {
        'underscore': {
            exports: '_'
        },
        'backbone': {
            deps: [
                'underscore',
                'jquery'
            ],
            exports: 'Backbone'
        },
        'fastclick': {
            exports: 'FastClick'
        },
        'phonegap': {
            exports: 'phonegap'
        },
        'cordova': {
            exports: 'cordova'
        },
        'sinon': {
            exports: 'sinon'
        }
    }

});

define(function(require) {

    "use strict";

    var // core libraries
        phonegap                = require('root/phonegap'),
        $                       = require('jquery'),
        _                       = require('vendor/underscore/underscore-1.5.2-min'),
        Backbone                = require('vendor/backbone/backbone-1.1.0-min'),
        FastClick               = require('vendor/fastclick/fastclick-0.6.11-min'),
        appConfig               = require('app/lib/xcelarys.app'),
        ScreenOverlayView       = require('app/views/overlay.screen.view'),
        sinon,
        test,

        // $elements
        $body;

    try {
        // Bootstrap test framework/server
        if (xcelarys.app.environ() === 'DEV' && xcelarys.app.testMode() === 'ON') {
            sinon               = require('test/sinon');
            test                = require('test/xcelarys.test');
        }

        // Perform page config
        FastClick.attach(document.body);    // Make click events fast!

        $body = $('body');

        var screenOverlayView = new ScreenOverlayView( { el: $body } );
        screenOverlayView.render();
        screenOverlayView.show( window.outerHeight, window.outerWidth );
    }
    catch(e) {
        console.log(e);
    }

});

これがビュー モジュール、overlay.screen.view.js です。

define( function( require ) {

    "use strict";

    var  $               = require('jquery'),
         _               = require('../../vendor/underscore/underscore-1.5.2-min'),
         Backbone        = require('../../vendor/backbone/backbone-1.1.0-min'),
         tmpl            = require('text!app/tmpl/overlayscreen.html'),
         template        = _.template(tmpl);  // // Uncaught TypeError: Cannot call method 'template' of undefined .

    alert($);
    alert(_);
    alert(Backbone);
    alert(template());

    return Backbone.View.extend({

        render: function() {

            this.$el.append(template());
            return this;

        },

        show: function( heightInPixels, widthInPixels ) {

            this.$('#overlayscreen').css('height', heightInPixels);
            this.$('#overlayscreen').css('width', widthInPixels);
            this.$('#overlayscreen').removeClass('hide');

        },

        hide: function() {

            this.$el.addClass('hide');

        }

    });

});

更新

以下のSeddassの投稿は、次の解決策につながります。基本的に、シムが期待どおりに機能するように、require.config() パスを更新する必要がありました。コードは次のとおりです。

require.config({
    baseUrl: '../../js',
    paths: {
        root: '..',
        jquery: 'vendor/jquery/jquery.2.0.3.min',
        underscore: 'vendor/underscore/underscore-1.5.2-min',
        backbone: 'vendor/backbone/backbone-1.1.0-min',
        test: 'test'
    },

    shim: {
        'jquery': {
            exports: '$'
        },
        'underscore': {
            exports: '_'
        },
        'backbone': {
            deps: [
                'underscore',
                'jquery'
            ],
            exports: 'Backbone'
        },
        'fastclick': {
            exports: 'FastClick'
        },
        'phonegap': {
            exports: 'phonegap'
        },
        'cordova': {
            exports: 'cordova'
        },
        'sinon': {
            exports: 'sinon'
        }
    }
});

require([
    'root/phonegap',
    'jquery',
    'underscore',
    'backbone',
    'vendor/fastclick/fastclick-0.6.11-min',
    'app/lib/xcelarys.app',

    // Views
    'app/views/overlay.screen.view',
    'app/views/global.header.1.view',

    // Models
    'app/models/global.header.1.models'
    ],
    function(
        phonegap,
        $,
        _,
        Backbone,
        FastClick,
        appConfig,
        ScreenOverlayView,
        GlobalHeader1,
        GlobalHeader1Model
    ) {
        "use strict";
        // code
    }
});

モジュール内のライブラリにアクセスできるようになりました。

define( function( require ) {
    "use strict";
    var  $               = require('jquery'),
         _               = require('underscore'),
         Backbone        = require('backbone'),
         tmpl            = require('text!app/tmpl/overlayscreen.html'),
         template        = _.template(tmpl);

    alert('overlay.screen#jquery = ' + $);
    alert('overlay.screen#underscore = ' + _);
    alert('overlay.screen#backbone = ' + Backbone);
    alert('overlay.screen#template' + template());

    // Code here!
});
4

2 に答える 2

2

Underscore.js のバージョンは AMD 対応ではないため、構成で shim を使用していると思います。しかし、私は電話するときにそれを信じています

require('../../vendor/underscore/underscore-1.5.2-min');

シムは、「_」のエクスポートを有効にするために「アンダースコア」を呼び出していることを認識できません。パス、シム設定、および後で同じパスでアンダースコアを要求するためにアンダースコアを設定しようとしましたか?

言い換えると:

require.config({
    ...
    paths: {
        'underscore' : '../../vendor/underscore/underscore-1.5.2-min',
        ....
    },
    shim: {
        'underscore' : {
             exports: '_'
        }
    }
});

ビュー(またはAMD jsファイル)で:

var _ = require('underscore'); 

動作するはずです。

于 2013-11-05T19:57:26.323 に答える
0

問題は、その時までに実行に移すことです

template        = _.template(tmpl);

underscorejs が完全に読み込まれていない可能性があります。非同期モジュール定義 (AMD) で「非同期」が意味する場所があります。コードを機能させるには、コードを次のように再構築する必要があります。

require(['underscore', 'text!app/tmpl/overlayscreen.html'], function (_, tmpl) {
    template        = _.template(tmpl);
    console.log (template);

});

こちらの例もご覧ください。

更新しました

hereで jsfiddle を使用して状況をシミュレートしました。すべてのモジュールが構成オブジェクトで定義されているため、次のように「sugar」バージョンでモジュール名を使用すると、機能するはずです。

var  $               = require('jquery'),
     _               = require('underscore'),
    Backbone         = require('backbone');
于 2013-11-05T16:54:13.960 に答える