Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将HandlebarJS与RequireJS一起使用,ReferenceError:未定义HandleBar_Javascript_Jquery_Requirejs_Handlebars.js - Fatal编程技术网

Javascript 将HandlebarJS与RequireJS一起使用,ReferenceError:未定义HandleBar

Javascript 将HandlebarJS与RequireJS一起使用,ReferenceError:未定义HandleBar,javascript,jquery,requirejs,handlebars.js,Javascript,Jquery,Requirejs,Handlebars.js,当使用requirejs加载handlebarjs时,我得到一个ReferenceError:Handlebars未定义消息 这是我在app.js文件中的配置 requirejs.config({ 'baseUrl': 'assets/js', 'paths': { 'handlebars' : 'plugins/handlebars', 'controller' : 'controller', 'initialize' : 'i

当使用requirejs加载handlebarjs时,我得到一个ReferenceError:Handlebars未定义消息

这是我在app.js文件中的配置

requirejs.config({
    'baseUrl': 'assets/js',
    'paths': {
        'handlebars' : 'plugins/handlebars',
        'controller' : 'controller',
        'initialize'  : 'initialize'
    },
    'shim' : {
        'handlebars': {
            exports: 'handlebars'
        },
        'controller' : {
            deps: [
                'handlebars'
            ]
        }
    }
});

requirejs([
    'handlebars',
    'initialize',
    'controller'
]);
在controller.js文件中,我有以下内容:

var source   = $("#entry-template").html();
var template = Handlebars.compile(source);

var context = {title: "My New Post", body: "This is my first post!"};
var ihtml    = template(context);

$('.testad').html(ihtml);
但是当我用这个包装上面的代码时,它似乎起作用了:

define(['handlebars'], function(Handlebars) {
    // place above code here
});
但问题是,我在define之外有一些方法无法调用它

define(['handlebars'], function(Handlebars) {
    // place above code here
    function handleMe() {
        // some codes here
    }
});

function callMe() {
    handleMe();
}
另一个问题是,我有一个initialize.js,它查找我的控制器属性并调用分配给它的函数。有点模块化

define(['jquery'], function($) {
$(function() {
    $('[my-controller]').each(function(e, t) {
        var a = $(t).attr('my-controller');
        'undefined' != typeof window[a] && $.isFunction(window[a]) ? window[a]($) : '';
    });
});

所以在我的HTML中,如果我有,它会自动调用callMe方法,它位于controller.js文件中。但是将callMe放在define中,无法调用它,因为它不再是全局的。

您遇到的所有问题都与作用域有关

在第一个问题中,handleMe仅作为包装它的工厂函数中的变量存在。没有任何东西能在闭包之外看到它。这与此类似:

var fn = function () {
    var a = 1;
};
console.log(a); // undefined
fn(); // a is set, but falls out of scope when the function returns
console.log(a); // still undefined
当您在共享范围或全局范围内声明变量时,此“问题”已修复,如下所示:

var a;
var fn = function () {
    a = 1;
}

console.log(a); // undefined
fn(); // a is set in the parent scope
console.log(a) // 1
// Controller.js
define(['handlebars'], function (handlebars) {
    var Controller = function () {
        // Create your controller here. 
        // Create any DOM elements you need here
    };
    Controller.prototype.initialize = function () {
        // Bind the DOM events to controller methods 
    };
    Controller.prototype.method1 = function () {};
    Controller.prototype.method2 = function () {};
    Controller.prototype.method3 = function () {};

    return Controller
});

// main.js
require(['Controller'], function (Controller) {
    var myController = new Controller();

    myController.initialize();
});
在第二个问题中,当您试图直接从DOM事件调用控制器方法时,除了尝试直接从全局范围窗口访问这些方法之外,您正在做同样的事情

我认为最好的解决方案是重新思考如何定义和组织模块。在典型的Requirejs项目中,通常您会这样定义模块:

var a;
var fn = function () {
    a = 1;
}

console.log(a); // undefined
fn(); // a is set in the parent scope
console.log(a) // 1
// Controller.js
define(['handlebars'], function (handlebars) {
    var Controller = function () {
        // Create your controller here. 
        // Create any DOM elements you need here
    };
    Controller.prototype.initialize = function () {
        // Bind the DOM events to controller methods 
    };
    Controller.prototype.method1 = function () {};
    Controller.prototype.method2 = function () {};
    Controller.prototype.method3 = function () {};

    return Controller
});

// main.js
require(['Controller'], function (Controller) {
    var myController = new Controller();

    myController.initialize();
});

谢谢安德鲁。我是否必须为每个定义创建一个新文件?就像上面给定的把手示例一样,我是否应该专门为把手逻辑创建controller-handlebar.js文件?创建另一个文件,比如controller-whateverplugin.js?我知道你可以让define['handlebar','whateverplugin'],function handlebar,whateverplugin{}但是如果依赖项太多,那就很难阅读了。有什么建议吗?这是使用require的最大优点之一,实际上它的主要用途和CommonJS一样,它是一个模块/加载程序/。每个define都有自己的文件。您也不需要将“controller.js”放在require.config的路径:[]部分。只要名称与Controller===assets/js/Controller.js匹配,Require就会知道在哪里找到它并在使用它之前加载它。就让它为你工作吧。声明可以很长,是的,但它只影响定义的第一行,作为回报,您可以拥有大量的代码库,而不必担心依赖性问题。