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

时间:2014-07-08 16:45:39

标签: javascript jquery angularjs

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

我们想开始在AngularJS中构建新功能(标签)并遇到一些问题。

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

我构建了一个简单的单页示例,展示了我们遇到的问题(在http://jsfiddle.net/p4v3G/1/下方或此处{{3}})。

我能够让这个例子工作的唯一方法是手动调用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>

2 个答案:

答案 0 :(得分:0)

要对您的应用进行分块,以便仅实例化相关部分等,您需要的是angular ui-router。然后,您将为选项卡控件设置父状态,并为每个选项卡设置子状态。这样,只需加载相关选项卡,您就可以获得深度链接和所需的性能。

至于requirejs,我鼓励你先考虑一下你是否真的需要它。在我看来,由于技术的声明性,构成角度应用程序的javascript通常比jquery应用程序更加简洁。因此,在启动时加载所有的JavaScript是可以的。但是,您的模板可能不那么简单,但通过使用templateUri对模板的引用,可以根据需要加载它们。 (我个人更喜欢将它们编译为javascript并将它们放在$ templateCahce中,但是这是另一回事。)

话虽如此,如果我的观察结果不适用于您的场景/应用程序/代码库,那么其他人已经成功地将requirejs与angularjs结合在一起。有关该主题的精彩介绍性演讲,请参阅此ng-conf video

祝你好运!

答案 1 :(得分:0)

你能更准确地说,会出现什么类型的错误。 你不需要使用jquery。检查此代码并进行比较 http://jsfiddle.net/pokaxperia/3w6pb/1/

<强> HTML

<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

<强> HTML

<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;
        };
      }
    };
  }
]);