16. AngularJS与其它框架的混用(jQuery, Dojo)


    这个问题似乎很多人都关心,但是事实是,如果了解了 ng 的工作方式,这本来就不是一个问题了。



    在我自己使用 ng 的过程当中,一直是混用 jQuery 的,以前还要加上一个 Dojo 。只要了解每种框架的工作方式,在具体的代码中每个框架都做了什么事,那么整体上控制起来就不会有问题。



    回到 ng 上来看,首先对于 jQuery 来说,最开始说提到过,在 DOM 操作部分, ng 与 jQuery 是兼容的,如果没有 jQuery , ng 自己也实现了兼容的部分 API 。



    同时,最开始也提到过, ng 的使用最忌讳的一点就是修改 DOM 结构——你应该使用 ng 的模板机制进行数据绑定,以此来控制 DOM 结构,而不是直接操作。换句话来说,在不动 DOM 结构的这个前提之下,你的数据随便怎么改,随便使用哪个框架来控制都是没问题的,到时如有必要使用 $scope.$digest() 来通知 ng 一下即可。



    下面这个例子,我们使用了 jQuery 中的 Deferred ( $.ajax 就是返回一个 Deferred ),还使用了 ng 的 $timeout ,当然是在 ng 的结构之下:

    1. 1 <!DOCTYPE html>
      2 <html ng-app="Demo">
      3 <head>
      4 <meta charset="utf-8" />
      5 <title>AngularJS</title>
      6 </head>
      7 <body>
      8
      9 <div ng-controller="TestCtrl">
      10 <span ng-click="go()">{{ a }}</span>
      11 </div>
      12
      13 <script type="text/javascript"
      14 src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js&quot;>
      15 </script>
      16 <script type="text/javascript"
      17 src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js&quot;>
      18 </script>
      19
      20 <script type="text/javascript">
      21 var app = angular.module('Demo', [], angular.noop);
      22 app.controller('TestCtrl', function($scope, $timeout){
      23 $scope.a = '点击我开始';
      24
      25 var defer = $.Deferred();
      26 var f = function(){
      27 if($scope.a == ''){$scope.a = '已停止'; return}
      28 defer.done(function(){
      29 $scope.a.length < 10 ? $scope.a += '>' : $scope.a = '>';
      30 $timeout(f, 100);
      31 });
      32 }
      33 defer.done(function(){$scope.a = '>'; f()});
      34
      35 $scope.go = function(){
      36 defer.resolve();
      37 $timeout(function(){$scope.a = ''}, 5000);
      38 }
      39 });
      40 </script>
      41 </body>
      42 </html>


    再把 Dojo 加进来看与 DOM 结构相关的例子。之前说过,使用 ng 就最好不要手动修改 DOM 结构,但这里说两点:


    1. 对于整个页面,你可以只在局部使用 ng ,不使用 ng 的地方你可以随意控制 DOM 。

    2. 如果 DOM 结构有变动,你可以在 DOM 结构定下来之后再初始化 ng 。


    下面这个例子使用了 AngularJSjQueryDojo

    1. 1 <!DOCTYPE html>
      2 <html>
      3 <head>
      4 <meta charset="utf-8" />
      5 <title>AngularJS</title>
      6 <link rel="stylesheet"
      7 href="http://ajax.googleapis.com/ajax/libs/dojo/1.9.1/dijit/themes/claro/claro.css&quot; media="screen" />
      8 </head>
      9 <body class="claro">
      10
      11 <div ng-controller="TestCtrl" id="test_ctrl">
      12
      13 <p ng-show="!btn_disable">
      14 <button ng-click="change()">调用dojo修改按钮</button>
      15 </p>
      16
      17 <p id="btn_wrapper">
      18 <button data-dojo-type="dijit/form/Button" type="button">{{ a }}</button>
      19 </p>
      20
      21 <p>
      22 <input ng-model="dialog_text" ng-init="dialog_text='对话框内容'" />
      23 <button ng-click="dialog(dialog_text)">显示对话框</button>
      24 </p>
      25
      26 <p ng-show="show_edit_text" style="display: none;">
      27 <span>需要编辑的内容:</span>
      28 <input ng-model="text" />
      29 </p>
      30
      31 <div id="editor_wrapper">
      32 <div data-dojo-type="dijit/Editor" id="editor"></div>
      33 </div>
      34
      35 </div>
      36
      37
      38 <script type="text/javascript"
      39 src="http://ajax.googleapis.com/ajax/libs/dojo/1.9.1/dojo/dojo.js&quot;>
      40 </script>
      41 <script type="text/javascript"
      42 src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js&quot;>
      43 </script>
      44 <script type="text/javascript"
      45 src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js&quot;>
      46 </script>
      47
      48 <script type="text/javascript">
      49
      50 require(['dojo/parser', 'dijit/Editor'], function(parser){
      51 parser.parse($('#editor_wrapper')[0]).then(function(){
      52 var app = angular.module('Demo', [], angular.noop);
      53
      54 app.controller('TestCtrl', function($scope, $timeout){
      55 $scope.a = '我是ng, 也是dojo';
      56 $scope.show_edit_text = true;
      57
      58 $scope.change = function(){
      59 $scope.a = 'DOM结构已经改变(不建议这样做)';
      60 require(['dojo/parser', 'dijit/form/Button', 'dojo/domReady!'],
      61 function(parser){
      62 parser.parse($('#btn_wrapper')[0]);
      63 $scope.btn_disable = true;
      64 }
      65 );
      66 }
      67
      68 $scope.dialog = function(text){
      69 require(["dijit/Dialog", "dojo/domReady!"], function(Dialog){
      70 var dialog = new Dialog({
      71 title: "对话框哦",
      72 content: text,
      73 style: "width: 300px"
      74 });
      75 dialog.show();
      76 });
      77 }
      78
      79 require(['dijit/registry'], function(registry){
      80 var editor = registry.byId('editor');
      81 $scope.$watch('text', function(new_v){
      82 editor.setValue(new_v);
      83 });
      84 });
      85
      86 });
      87
      88 angular.bootstrap(document, ['Demo']);
      89 });
      90
      91 });
      92
      93 </script>
      94 </body>
      95 </html>