具有模块自治的Javascript单页架构

时间:2012-08-17 18:39:46

标签: javascript jquery

我刚开始这个HTML5项目,我们决定通过利用jQuery $ .load()方法使其成为单页面体系结构。不幸的是,一旦JS开始发展,我们很快就开始遇到加载到主仪表板中的模块不知道其父级的问题。

架构如下所示:

dashboard.html(主文件)
moduleA.html
moduleA.js
moduleB.html
moduleB.js
moduleC.html
moduleC.js

由于我们决定将JS保留为单独的文件,因此我们必须通过dashboard.html加载所有JS文件,以便在加载modulex时单独调用它们。

因此,当将moduleA.html加载到仪表板时,我们必须调用其相应的JS。为此,我们使用模块模式编写JS,以便通过执行函数调用轻松调用它,如:

<script>

moduleA

</script>

或者如果我们想要访问该成员的特定属性。

<script>

moduleA.someMethod();

</script>

现在,我知道有更好的办法,对吧?我讨厌在HTML模块中加载脚本标签以加载相应的JS文件。

另一个限制是我们不再单独处理模块这一事实,因为脚本和CSS调用发生在父(dashboard.html)上,所以当dcA.html直接加载时,它是纯HTML的没有脚本或CSS。

我查看了其他问题,但我没有看到任何人遇到同样的问题。

我查看了AngularJS,EmberJS,KO.JS和BoilerPlateJS,但没有一个解决我们想要完成的任务。唯一一个具有相似单页概念的是jQuery Mobile,但我不知道你是否可以从jQuery切换到jQuery Mobile,一切都还在继续。

有没有人面对这个问题呢?有解决方案还是我必须使用自定义解决方案。

谢谢!

2 个答案:

答案 0 :(得分:2)

我可以和你争论AngularJS。这正是你需要的

dashboard.html是附加了一些指令的布局,但如果你使用ng-view指令,那么权力就在于AngularJs

这里是例子:

<强> dashboard.js

var app = angular.module("modularApp",[]);
app.config(['$routeProvider', "$locationProvider", function routes($routeProvider, $locationProvider) {
    $routeProvider.when('/dashboard', {
        controller:'HomeCtrl',
        templateUrl:'templates/home.html'
    });    
    $routeProvider.when('/moduleA', {
        controller:'ModuleACtrl',
        templateUrl:'templates/moduleA.html'
    });
    $routeProvider.when('/moduleB', {
        controller:'ModuleBCtrl',
        templateUrl:'templates/moduleB.html'
    });
    $routeProvider.otherwise({redirectTo: "/dashboard"});
}]);

<强>模板/ dashboard.html

<html ng-app="modularApp">
<head>
  <!--.... include angular minified js file and what else you need...-->
  <script type="text/javascript" src="dashboard.js"></script>
  <script type="text/javascript" src="moduleACtrl.js"></script>
  <script type="text/javascript" src="moduleBCtrl.js"></script>
</head>
<body>
  <a ng-href="#/moduleA">Open Module A View</a>
  <a ng-href="#/moduleB">Open Module B View</a>
  <!-- Add widgets header menus .... -->
  <ng-view></ng-view>
</body>
</html>

<强> moduleACtrl.js

var app=angular.module("modularApp");
app.controller("ModuleACtrl",function($scope){
  $scope.scopeValue="Hellow from view";
});

<强> moduleBCtrl.js

var app=angular.module("modularApp");
app.controller("ModuleBCtrl",function($scope){
  $scope.scopeValue="Hellow from another view";
});

<强>模板/ moduleA.html

<div>{{scopeValue}} in module A</div>

<强>模板/ moduleB.html

<div>{{scopeValue}} in module B</div>

你可以用角度来做更复杂的事情。一切都取决于您的需求。您有什么特殊要求:)


此外,您可以创建自己的指令,例如ng-view并使用您自己的$ route服务和$ routeProvider,这样您就可以在某些rute匹配url时添加要动态加载的css和javascript。

所以代替上面的路由表,你可以有

app.config(['$myRouteProvider', "$locationProvider", function routes($routeProvider, $locationProvider) {
        $routeProvider.when('/dashboard', {
            javascript:'javascript/dashboard.js',
            templateUrl:'templates/dashboard.html',
            cssfile: 'css/dashboard.css'
        });    
        $routeProvider.when('/moduleA', {
            javascript:'javascript/moduleA.js',
            templateUrl:'templates/moduleA.html',
            cssfile: 'css/moduleA.css'
        });
        $routeProvider.when('/moduleB', {
            javascript:'javascript/moduleB.js',
            templateUrl:'templates/moduleB.html',
            cssfile: 'css/moduleB.css'

        });
        $routeProvider.otherwise({redirectTo: "/dashboard"});
    }]);

但是,请原谅我的法国人,屁股。我在rails上尝试使用Ruby中的几个lib来实现类似,但后端是渲染内容,或者只是内容的一部分。但是我不确定你使用的是哪个后端,你是否有兴趣切换到rails。

答案 1 :(得分:0)

BoilerplateJS中的DomController可以满足您的需求,而无需使用任何自定义HTML属性。您的dashboard.html可以将占位符放在您要注入组件的位置。我只是从BoilerplateJS index.html中提取下面的一些html来展示它是如何工作的:

<body>
    <section id="page-content">
        <header>
            <section class="theme"></section>
            <section class="language"></section>
        </header>
        <aside>
            <section class="main-menu"></section>
        </aside>
    </section>
</body>

上面的主题,语言和主菜单部分只是占位符,DomController将向其注入相关组件。 DomController现在可用于使用适当的选择器注册组件,如下所示:

    //scoped DomController that will be effective only on $('#page-content')
    var controller = new Boiler.DomController($('#page-content'));
    //add routes with DOM node selector queries and relavant components
    controller.addRoutes({
        ".main-menu" : new MainMenuRouteHandler(context),
        ".language" : new LanguageRouteHandler(context),
        ".theme" : new ThemeRouteHandler(context)
    });
    controller.start();

以上代码摘自“/boilerplatejs/src/modules/baseModule/module.js”