一步一步弄懂angularJS基础

前端之家收集整理的这篇文章主要介绍了一步一步弄懂angularJS基础前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

问题1:ng-app指令的使用以及自定义指令

  1. <!doctype html>
  2. <!--这里的ng-app的属性值就是模块的名称,也就是 angular.module("MyModule",[])中的MyModule-->
  3. <html ng-app="MyModule">
  4. <head>
  5. <Meta charset="utf-8">
  6. </head>
  7. <body>
  8. <hello></hello>
  9. <!--这个标签被完全替换为'<div>Hi everyone!</div>',这一点很重要的-->
  10. </body>
  11. <script src="js/angular-1.3.0.js"></script>
  12. <!--引入指令-->
  13. <script src="HelloAngular_Directive.js"></script>
  14. </html>
我们看看指令本身的代码是如何定义的
  1. var myModule = angular.module("MyModule",[]);
  2. //创建一个模块
  3. myModule.directive("hello",function() {
  4. //这里的指令为hello指令,而且是Element类型,返回的template就是用于替换hello的部分,而replace指定了用template值替换了hello这个标签内容
  5. return {
  6. restrict: 'E',template: '<div>Hi everyone!</div>',replace: true
  7. }
  8. });
问题2:我们来理解一下angularjs的MVC模式
  1. <!doctype html>
  2. <!--这里的ng-app指令表明下面的所有的指令全部让angularjs处理,只有被具有ng-app属性的DOM元素包含的元素才会受到angularjs的影响-->
  3. <html ng-app>
  4. <head>
  5. <Meta charset="utf-8">
  6. </head>
  7. <body>
  8. <!--这里指定了一个controller,这个controller是view视图和数据之间的桥梁-->
  9. <div ng-controller="HelloAngular">
  10. <!--这里指定的视图,也就是用于显示的view-->
  11. <p>{{greeting.text}},Angular</p>
  12. </div>
  13. </body>
  14. <script src="js/angular-1.3.0.js"></script>
  15. <script src="HelloAngular_MVC.js"></script>
  16. </html>
下面是控制器的代码
  1. function HelloAngular($scope) {
  2. $scope.greeting = {
  3. text: 'Hello'
  4. };
  5. }
问题3:通用controller是通过$scope来完成继承的,但是我们不建议使用通用controller,而是使用服务
  1. <!doctype html>
  2. <html ng-app>
  3. <head>
  4. <Meta charset="utf-8">
  5. </head>
  6. <body>
  7. <!--这里是CommonController的部分,这个controller指定了内部两个controller共有的逻辑-->
  8. <div ng-controller="CommonController">
  9. <!--这里是内部第一个controller-->
  10. <div ng-controller="Controller1">
  11. <p>{{greeting.text}},Angular</p>
  12. <button ng-click="test1()">test1</button>
  13. </div>
  14. <!--这里是内部第二个controller-->
  15. <div ng-controller="Controller2">
  16. <p>{{greeting.text}},Angular</p>
  17. <button ng-click="test2()">test2</button>
  18. <button ng-click="commonFn()">通用</button>
  19. </div>
  20. </div>
  21. </body>
  22. <script src="js/angular-1.3.0.js"></script>
  23. <script src="MVC3.js"></script>
  24. </html>
下面是三个controller的代码
  1. //这个通用的controller指定的是两个controller都具有的方法
  2. function CommonController($scope){
  3. $scope.commonFn=function(){
  4. alert("这里是通用功能!");
  5. };
  6. }
  7. //这里是第一个controller指定了其特有的功能
  8. function Controller1($scope) {
  9. $scope.greeting = {
  10. text: 'Hello1'
  11. };
  12. $scope.test1=function(){
  13. alert("test1");
  14. };
  15. }
  16. //这里是第一个controller指定了其特有的功能
  17. function Controller2($scope) {
  18. $scope.greeting = {
  19. text: 'Hello2'
  20. };
  21. $scope.test2=function(){
  22. alert("test2");
  23. }
  24. }

注意:其实$scope是一个POJO(plain Old JavaScript Object);$scope提供了一些工具方法,如$watch,$apply等;$scope是表达式执行环境,也就是作用域;$scope是树形结构和DOM标签平行;子$scope继承父$scope的所有的属性方法;每一个angular应用只有一个根$scope,一般位于ng-app上;$scope可以用于传播事件,类似DOM可以往上也可以往下;可以用angular.element($0).scope进行调试。总之,$scope不仅仅是MVC的基础,而且也是双向数据绑定的基础!

问题4:ng-repeat的使用,同时指定了$scope会继承$rootScope,就像原型链一样

  1. <!doctype html>
  2. <html ng-app>
  3. <head>
  4. <Meta charset="utf-8">
  5. <link rel="stylesheet" type="text/css" href="Scope1.css" />
  6. </head>
  7. <body>
  8. <div class="show-scope-demo">
  9. <!--这里是第一个controller,是GreetCtrl-->
  10. <div ng-controller="GreetCtrl">
  11. Hello {{name}}!
  12. </div>
  13. <!--这里是第二个controller,是ListCtrl-->
  14. <div ng-controller="ListCtrl">
  15. <ol>
  16. <!--ng-repeat指令的使用-->
  17. <li ng-repeat="name in names">
  18. {{name}} from {{department}}
  19. </li>
  20. </ol>
  21. </div>
  22. </div>
  23. </body>
  24. <script src="js/angular-1.3.0.js"></script>
  25. <script src="Scope1.js"></script>
  26. </html>
下面是两个controller,同时注意这时候$scope会继承$rootScope的属性
  1. //第一个controller指定了$scope和$rootScope,并且在他们上面都绑定了属性
  2. function GreetCtrl($scope,$rootScope) {
  3. $scope.name = 'World';
  4. $rootScope.department = 'Angular';
  5. }
  6. //这里也绑定了$scope属性
  7. function ListCtrl($scope) {
  8. $scope.names = ['Igor','Misko','Vojta'];
  9. }
问题5:我们来看看$emit和$broadcast用于事件触发的不同
  1. <!doctype html>
  2. <html ng-app>
  3. <head>
  4. <Meta charset="utf-8">
  5. <link rel="stylesheet" type="text/css" href="Scope1.css" />
  6. </head>
  7. <body>
  8. <!--第一个控制器EventController-->
  9. <div ng-controller="EventController">
  10. Root scope
  11. <tt>MyEvent</tt> count: {{count}}
  12. <ul>
  13. <!--这里是内部的controller,也是通过EventController来控制的-->
  14. <li ng-repeat="i in [1]" ng-controller="EventController">
  15. <!--这里是调用$emit-->
  16. <button ng-click="$emit('MyEvent')">
  17. $emit('MyEvent')
  18. </button>
  19. <!--这里是调用$broadcast-->
  20. <button ng-click="$broadcast('MyEvent')">
  21. $broadcast('MyEvent')
  22. </button>
  23. <br>
  24. Middle scope
  25. <tt>MyEvent</tt> count: {{count}}
  26. <!--EventController-->
  27. <ul>
  28. <li ng-repeat="item in [1,2]" ng-controller="EventController">
  29. Leaf scope
  30. <tt>MyEvent</tt> count: {{count}}
  31. </li>
  32. </ul>
  33. </li>
  34. </ul>
  35. </div>
  36. </body>
  37. <script src="js/angular-1.3.0.js"></script>
  38. <script src="Scope2.js"></script>
  39. </html>
下面是控制器的代码
  1. function EventController($scope) {
  2. $scope.count = 0;
  3. //这个$scope具有$on方法来监测具体的事件,这里是监测'MyEvent'事件,每次监听到这个事件就把count++
  4. $scope.$on('MyEvent',function() {
  5. $scope.count++;
  6. });
  7. }
通过测试我们发现$emit触发事件会导致从同级作用域不断往上传播,但是$broadCast会使得事件从同级作用域不断往下传播。但是不管是$emit还是$broadcast都会在同级作用域之间传播。

问题6:我们看看如何让angularjs实现了站内路由,其本质还是通过hash来完成的

  1. <!doctype html>
  2. <html ng-app="bookStoreApp">
  3. <head>
  4. <Meta charset="UTF-8">
  5. <title>BookStore</title>
  6. <!--当express直接访问/的时候被重定向到这里,然后静态资源文件如js等都是在public目录下进行加载的-->
  7. <script src="1.3.0.14/angular.js"></script>
  8. <script src="1.3.0.14/angular-route.js"></script>
  9. <script src="1.3.0.14/angular-animate.js"></script>
  10. <!--然后加载app.js,这是一个模块,定义了该模块依赖的一些如控制器,过滤器,服务,指令等-->
  11. <script src="app.js"></script>
  12. <script src="controllers.js"></script>
  13. <script src="filters.js"></script>
  14. <script src="services.js"></script>
  15. <script src="directives.js"></script>
  16. </head>
  17. <body>
  18. <!--这里是视图显示区域-->
  19. <div ng-view>
  20. </div>
  21. </body>
  22. </html>

我们再来看看app.js中如何指定了依赖模块,同时是如何实现站内路由的。注意:ng-view是由ngRouter模块提供的一个特殊指令,他的独特之处是在HTML中给$router对应的视图内容占位,他会创建自己的作用域并将模版嵌套在内部。ng-view是一个优先级为1000的终极指令,angularjs不会运行同一个元素上的低优先级指令。ngView指令遵循下面的规则:

。每次触发$routeChangeSuccess事件视图都会更新

。如果某个模版和当前的路由相关联:

(1)创建一个新的作用域;(2)移除上一个视图,同时上一个作用域也会被清除;(3)将新的作用域和当前模版关联在一起;(4)如果路由中有相关的定义,那么就把对应的控制器和当前作用域关联起来;(5)触发$viewContentLoaded事件;(6)如果提供了onload属性调用属性指定的函数

  1. //定义了一个模块bookStoreApp,第二个参数是该模块依赖的模块。其中<bookStoreCtrls>是一个模块,其中封装了两个控制器分别为bookStoreCtrls,BookListCtrl
  2. //其中模块<bookStoreFilters>是一个过滤器
  3. //模块<bookStoreServices>定义了一个服务
  4. //模块<bookStoreDirectives>定义了一个指令集合
  5. var bookStoreApp = angular.module('bookStoreApp',[
  6. 'ngRoute','ngAnimate','bookStoreCtrls','bookStoreFilters','bookStoreServices','bookStoreDirectives'
  7. ]);
  8. //在这个app模块中我们配置了路由,如果是访问了hello就会重定向到http://localhost:3008/hello这个视图文件
  9. //同时这个视图文件通过HelloCtrl这个控制器进行渲染
  10. bookStoreApp.config(function($routeProvider) {
  11. $routeProvider.when('/hello',{
  12. templateUrl: 'http://localhost:3008/hello',controller: 'HelloCtrl'
  13. }).when('/list',{
  14. //如果是list那么渲染视图http://localhost:3008/bookList,同时渲染工作由BookListCtrl来完成
  15. templateUrl:'http://localhost:3008/bookList',controller:'BookListCtrl'
  16. }).otherwise({
  17. redirectTo: '/hello'
  18. })
  19. });
很显然是通过模块的config方法来完成的,同时实现了注入$routeProvider对象,最后通过这个对象的when...otherwise方法来实现路由的。记住,上面的ng-view是指定了视图的显示区域。其站内路由还是通过hash来完成的:


我们谈谈ajax:ajax的页面浏览器回退按钮会失效;无法分享页面,也就无法加书签;SEO无法起作用,于是就有了前端路由的观点。前端路由的原理:通过hash值#;HTML5提供的API也可以完成;路由的核心是给应用定义"状态";使用路由会影响应用整体的编码方式(预先定义好状态);考虑兼容性问题与优雅降级。

问题7:我们建议在定义controller时候不是在函数中直接定义,而是在模块中定义:

第一种方式直接在函数中定义:

  1. function HelloAngular($scope) {
  2. $scope.greeting = {
  3. text: 'Hello'
  4. };
  5. }
第二种方式是首先定义模块,然后在模块中定义控制器,这是我们推荐的方式:
  1. var helloModule=angular.module('HelloAngular',[]);
  2. helloModule.controller('helloNgCtrl',['$scope',function($scope){
  3. $scope.greeting = {
  4. text: 'Hello'
  5. };
  6. }]);

我们推荐下面的编码逻辑:

问题7:使用ng-bind防止页面快速刷新或者网速较慢的时候看到源代码{{greeting.text}}

  1. <!doctype html>
  2. <html ng-app>
  3. <head>
  4. <Meta charset="utf-8">
  5. </head>
  6. <body>
  7. <!--引用一个控制器HelloAngular-->
  8. <div ng-controller="HelloAngular">
  9. <!--ng-bind用于绑定,之所有使用ng-bind而不是使用{{greeting.text}}是因为在网速慢的时候或者快速刷新的时候会看到{{greeting.text}}这个源代码-->
  10. <p><span ng-bind="greeting.text"></span>,Angular</p>
  11. </div>
  12. </body>
  13. <script src="js/angular-1.3.0.js"></script>
  14. <script src="HelloAngular_MVC.js"></script>
  15. </html>
控制器代码如下(建议用模块来定义):
  1. function HelloAngular($scope) {
  2. $scope.greeting = {
  3. text: 'Hello'
  4. };
  5. }
问题8:使用ng-class来添加class,而不是使用为$scope添加属性这种方式
  1. <!doctype html>
  2. <html ng-app="MyCSSModule">
  3. <head>
  4. <Meta charset="utf-8">
  5. <link rel="stylesheet" href="NgClass.css">
  6. </head>
  7. <body>
  8. <!--这里是控制器HeaderController,如果isError为true那么添加error类,如果isWarning为true那么谈价类warning就可以了-->
  9. <div ng-controller='HeaderController'>
  10. <!--这里是视图,其类名和提示信息都是动态添加的,这一点要弄清楚-->
  11. <div ng-class='{error: isError,warning: isWarning}'>{{messageText}}</div>
  12. <button ng-click='showError()'>Simulate Error</button>
  13. <button ng-click='showWarning()'>Simulate Warning</button>
  14. </div>
  15. </body>
  16. <script src="js/angular-1.3.0.js"></script>
  17. <script src="NgClass.js"></script>
  18. </html>
同时相应的点击事件来修改数据模型中的值,进而使得视图内容能够动态改变,而视图的样式通过ng-class来修改了。除了ng-class另外一种使用 细说Angular ng-class
  1. var myCSSModule = angular.module('MyCSSModule',[]);
  2. //定义一个模块MyCSSModule
  3. myCSSModule.controller('HeaderController',//为模块定义个控制器HeaderController
  4. function($scope) {
  5. $scope.isError = false;
  6. $scope.isWarning = false;
  7. $scope.showError = function() {
  8. $scope.messageText = 'This is an error!';
  9. $scope.isError = true;
  10. $scope.isWarning = false;
  11. };
  12. $scope.showWarning = function() {
  13. $scope.messageText = 'Just a warning. Please carry on.';
  14. $scope.isWarning = true;
  15. $scope.isError = false;
  16. };
  17. }
  18. ])
问题8:使用ng-show来控制元素的隐藏和显示
  1. <!doctype html>
  2. <html ng-app="MyCSSModule">
  3. <head>
  4. <Meta charset="utf-8">
  5. </head>
  6. <body>
  7. <div ng-controller='DeathrayMenuController'>
  8. <!--点击的时候就触发toggleMenu逻辑,在该方法里面修改了数据模型的值-->
  9. <button ng-click='toggleMenu()'>Toggle Menu</button>
  10. <!--ng-show指令通过判断表达式的值进而决定是否应该显示内容-->
  11. <ul ng-show='menuState.show'>
  12. <li ng-click='stun()'>Stun</li>
  13. <li ng-click='disintegrate()'>Disintegrate</li>
  14. <li ng-click='erase()'>Erase from history</li>
  15. </ul>
  16. <div/>
  17. </body>
  18. <script src="js/angular-1.3.0.js"></script>
  19. <script src="NgShow.js"></script>
  20. </html>
控制器内部通过非表达式来实现开关效果
  1. var myCSSModule = angular.module('MyCSSModule',[]);
  2. //这里定义一个模块<MyCSSModule>,在模块上定义一个控制器DeathrayMenuController
  3. myCSSModule.controller('DeathrayMenuController',function($scope) {
  4. $scope.menuState={show:false};
  5. $scope.toggleMenu = function() {
  6. //这里的toggleMenu通过非符号'!'就能够动态改变了
  7. $scope.menuState.show = !$scope.menuState.show;
  8. };
  9. }
  10. ])
上面演示了如何实现jQuery中的toggleClass效果

猜你在找的Angularjs相关文章