在现有的基于jquery/bootstrap的网站中嵌入AngularJS

Embedding AngularJS in existing jquery/bootstrap based website

本文关键字:网站 bootstrap AngularJS jquery      更新时间:2023-09-26

我们有一个现有的应用程序,其中客户端是jQuery/Bootstrap。它由许多选项卡组成,其中每个选项卡都在通过导入的模块中定义。require.js。标签javascript被赋予了一个父DOM元素,并负责在该元素内部绘制自己。

我们想开始在AngularJS中构建新的功能(选项卡),但是遇到了一些问题。

我的想法是,我们可以用ng-app标记主体,并在主页代码中召唤一个应用模块window.app = angular.module('ourApp', []);,然后,随着选项卡加载,创建并连接控制器。

我已经构建了一个简单的单页示例,展示了我们遇到的问题(下面或这里http://jsfiddle.net/p4v3G/1/)。

我已经能够得到的例子工作的唯一方法是手动调用angular.bootstrap,我很确定是错误的。而且,这只在第一次有效,所以如果我点击这个按钮两次(相当于导航到标签页,离开它,然后在我们的应用程序中再次返回),Angular就不会正常连接。

我很感激你的帮助。

<body ng-app='testApp'>
    <div id="main" style="border: 1px solid #000; background: #ffdddd;">Click button to replace template and wire up controller...</div>
    <button id="button1">Load</button>
    <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.14/angular.min.js"></script>
    <script>
        var app = angular.module('testApp', []);
        jQuery(function() {
            $("button").click(function() {
                // controllers are wired up in click handler to simulate environment where we
                // are looking to embed angular inside of an existing bootstrap/jquery application 
                // where new tabs (loaded as separate modules through require) are loaded on-demand.
                app.controller('TestController', function($scope) {
                    $scope.message = 'Hello World, from Controller #1';
                });
                $("#main").html('<div ng-controller="TestController">{{message}}</div>');
                // Bootstrap works the first click but not subsequent clicks
                angular.bootstrap(document, ['testApp']);
            });
        });
    </script>
</body>

要把应用分成块,只实例化相关的部分等,你需要的是angular ui-router。然后为选项卡控件设置父状态,并为每个选项卡设置子状态。这样,你既可以获得深度链接,又可以获得只加载相关选项卡所需的性能。

关于需求,我建议你先考虑一下你是否真的需要它。在我看来,由于该技术的声明性,组成angular应用程序的javascript通常比jquery应用程序简洁得多。因此,在启动时加载所有javascript是可以的。然而,您的模板可能没有那么简单,但是通过使用templateUri对模板的引用,可以根据需要加载它们。(就我个人而言,我更喜欢将它们编译成javascript,并将它们放在$templateCahce中,但这是另一回事。)

话虽这么说,如果我的观察并不适用于你的场景/应用程序/代码库,那么其他人已经非常成功地将需求与angularjs结合起来了。有关这个主题的介绍性演讲,请参见这个视频。

祝你好运!

你能不能再精确一点,出现了什么类型的错误?您不需要使用jquery。检查此代码并进行比较http://jsfiddle.net/pokaxperia/3w6pb/1/

<body ng-app='testApp'>
    <div ng-controller="TestController">    
        <span id="main" style="border: 1px solid #000; background: #ffdddd;">{{message}}</span>
        <button ng-click="loadMessage();" id="button1">Load</button>
    </div>   
    <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
</body>
脚本

var app = angular.module('testApp', []);
app.controller('TestController', ['$scope',function($scope) {
    $scope.message = "Click button to replace template and wire up controller...";
    $scope.loadMessage = function(){
        $scope.message = 'Hello World, from Controller #1';
    };
}]);

或者在jsfiddle上检查您的代码,但是只有很少的变体http://plnkr.co/edit/fUQDpO?p=preview

<body>
    <example-tabs></example-tabs>
    <div class="panel" ng-show="isSelected(1)">Panel One</div>
    <div class="panel" ng-show="isSelected(2)">Panel Two</div>
    <div class="panel" ng-show="isSelected(3)">Panel Three</div>
</body>
主脚本:

var app = angular.module('tabsExample', ['tabDirectives']);

加载选项卡的指令

var app = angular.module('tabDirectives', []);
app.directive('exampleTabs', [
  function() {
    return {
      restrict: 'E',
      templateUrl: 'example-tabs.html',
      controller: function($scope) {
        $scope.tab = 1;
        $scope.selectedTab = function(setTab) {
          $scope.tab = setTab;
        };
        $scope.isSelected = function(checkTab) {
          return $scope.tab === checkTab;
        };
      }
    };
  }
]);