加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

一步一步弄懂angularJS基础

发布时间:2020-12-17 10:11:25 所属栏目:安全 来源:网络整理
导读:问题1:ng-app指令的使用以及自定义指令 !doctype html!--这里的ng-app的属性值就是模块的名称,也就是 angular.module("MyModule",[])中的MyModule--html ng-app="MyModule"headmeta charset="utf-8"/headbodyhello/hello !--这个标签被完全替换为'divHi ev

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

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

注意:其实$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,就像原型链一样

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读