使用带有RequireJS的HandlebarJS,ReferenceError:未定义Handlebars

时间:2015-10-01 04:41:44

标签: javascript jquery requirejs handlebars.js

使用requirejs加载handlebarjs时,我收到function (reducer, initialState) { var store = next(reducer, initialState); var _dispatch = store.dispatch; var chain = []; var middlewareAPI = { getState: store.… 消息。

这是app.js文件中的配置

devToolsStore: Object
dispatch: (action)
getReducer: getReducer()
getState: getState()
replaceReducer: replaceReducer(nextReducer)
subscribe: subscribe(listener)

在controller.js文件中我有:

import React, { Component } from 'react';
import { Provider } from 'react-redux';
import configureStore from '../store/configureStore';

import { createStore, applyMiddleware, combineReducers, compose } from 'redux';
import { DevTools, DebugPanel, LogMonitor } from 'redux-devtools/lib/react';


import AsyncApp from './AsyncApp';

const store = configureStore();

export default class Root extends Component {
  render() {
return (
 <div>
  <Provider store={store}>
    {() => <AsyncApp />}
  </Provider>
  <DebugPanel top right bottom>
    <DevTools store={store} monitor={LogMonitor} />
  </DebugPanel>
</div>
);
}
}

但是当我用上面的代码包装上面的代码时,似乎有效:

import { createStore, applyMiddleware, combineReducers, compose } from "redux";
import thunkMiddleware from "redux-thunk";
import loggerMiddleware from "redux-logger";
import rootReducer from "../reducers";
import thunk from 'redux-thunk';
import { devTools, persistState } from 'redux-devtools';

const finalCreateStore = compose(
    applyMiddleware(thunkMiddleware),
    devTools(),
    persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/)),
    createStore
);

export default function configureStore(initialState) {
  return finalCreateStore(rootReducer, initialState);
}

但问题是,我在ReferenceError: Handlebars is not defined之外的方法中无法调用它。

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

requirejs([
    'handlebars',
    'initialize',
    'controller'
]);

另一个问题是,我有一个initialize.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
});

因此,在我的HTML中,如果我有define(),它会自动调用define(['handlebars'], function(Handlebars) { // place above code here function handleMe() { // some codes here } }); function callMe() { handleMe(); } 方法,它位于我的controller.js文件中。但是将my-controller置于内部定义中,它无法被调用,因为它不再是全局的。

1 个答案:

答案 0 :(得分:0)

您遇到的所有问题都与范围有关。

在您的第一个问题中,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

在第二个问题中,您尝试直接从DOM事件调用控制器方法,除了尝试直接从全局范围(window)访问方法之外,您正在做同样的事情。 p>

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

// 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();
});