angularjs中的隔离作用域理解以及绑定策略

我们首先看下面的例子:

<!doctype html>
<html ng-app="MyModule">
	<head>
		<meta charset="utf-8">
		<link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css">
	</head>
	<body>
		<hello></hello>
		<hello></hello>
		<hello></hello>
		<hello></hello>
	</body>
	<script src="framework/angular-1.3.0.14/angular.js"></script>
	<script src="IsolateScope.js"></script>
</html>
我们在看看IsolateScope中的代码:

var myModule = angular.module("MyModule", []);
myModule.directive("hello", function() {
    return {
        restrict: 'AE',
        template: '<div><input type="text" ng-model="userName"/>{{userName}}</div>',
        replace: true
    }
});

这时候当运行页面的时候发现只要有一个input中的输入变化了,这时候所有的nput的内容都会变化:


这样就会面临一个问题:我们的指令无法单独使用,于是就有了独立作用域的概念。

var myModule = angular.module("MyModule", []);
myModule.directive("hello", function() {
    return {
        restrict: 'AE',
        scope:{},
        template: '<div><input type="text" ng-model="userName"/>{{userName}}</div>',
        replace: true
    }
});
通过把scope设置为{},那么每一个指令就具有自己独立的scope空间,于是就不会相互影响了。但是angularjs中最重要的概念是: 绑定策略。其具有绑定策略如下:


第一步:我们看看原始的方式,也就是不使用上面的三种绑定方式

<!doctype html>
<html ng-app="MyModule">
	<head>
		<meta charset="utf-8">
		<link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css">
	</head>
	<body>
	<!--控制器MyCtrl下面有指令drink,同时指令drink还有自定义的属性flavor,其值为‘百威’-->
		<div ng-controller="MyCtrl">
			<drink flavor="{{ctrlFlavor}}"></drink>
		</div>
	</body>
	<script src="framework/angular-1.3.0.14/angular.js"></script>
	<script src="ScopeAt.js"></script>
</html>
看看ScopeAt中的内容:

var myModule = angular.module("MyModule", []);
myModule.controller('MyCtrl', ['$scope', function($scope){
	$scope.ctrlFlavor="百威";
    //在控制器中$scope中设置了ctrlFlavor属性
}])
//定义了drink指令
myModule.directive("drink", function() {
    return {
    	restrict:'AE',
        template:"<div>{{flavor}}</div>" ,
         link:function(scope,element,attrs){
         	scope.flavor=attrs.flavor;
            //链接的时候把drink指令上的flavor属性放在scope中,然后在template中显示
         }
    }
});
这时候的DOM结构如下:


但是,这种方式要通过attrs.flavor来获取这个指令的属性值,然后需要把这个属性值绑定到scope对象上,最后在template中才能通过{{}}这种形式获取到scope中的值!
第二步:我们使用上面的@来替换第一种方式,因为它每次都需要自己指定link函数:

var myModule = angular.module("MyModule", []);
myModule.controller('MyCtrl', ['$scope', function($scope){
	$scope.ctrlFlavor="百威";
    //在控制器中$scope中设置了ctrlFlavor属性
}])
//定义了drink指令
myModule.directive("drink", function() {
    return {
    	restrict:'AE',
        scope:{
        	flavor:'@'
        },
        template:"<div>{{flavor}}</div>" 
    }
});
这种方式就是把 指令drink中的flavor属性值绑定到scope对象上,而且这是ng为我们自动绑定的。不过,@绑定绑定的是字符串,而不是对象!

第三步:我们来学习一下双向数据绑定

<!doctype html>
<html ng-app="MyModule">
	<head>
		<meta charset="utf-8">
		<link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css">
	</head>
	<body>
	<!--指定了控制器MyCtrl-->
		<div ng-controller="MyCtrl">
			Ctrl:
			<br>
			<!--第一个输入框输入值绑定到ctrlFlavor,也就是控制器MyCtrl对应的ctrlFlavor值中-->
			<input type="text" ng-model="ctrlFlavor">
			<br>
			Directive:
			<br>
			<!--第二个输入框还是通过指令的方式来完成的-->
			<drink flavor="ctrlFlavor"></drink>
		</div>
	</body>
	<script src="framework/angular-1.3.0.14/angular.js"></script>
	<script src="ScopeEqual.js"></script>
</html>
我们再来看看控制器中内容

var myModule = angular.module("MyModule", []);
//指定了控制器对象
myModule.controller('MyCtrl', ['$scope', function($scope){
	$scope.ctrlFlavor="百威";
}])
//指定了指令
myModule.directive("drink", function() {
    return {
    	restrict:'AE',
        scope:{
        	flavor:'='
        	//这里通过'='指定了drink指令的flavor和scope中的双向数据绑定!
        },
        template:'<input type="text" ng-model="flavor"/>'
    }
});
这就是'='这种绑定方式。其实现了双向的数据绑定策略。我们看看最后的DOM结构是怎么样的:


其实双向数据绑定<drink flavor="ctrlFlavor"></drink>是很明显的,需要好好理解双向数据绑定(指令和控制器之间的双向数据绑定)

第四步:我们使用&绑定策略来完成对controller父级方法的调用:

<!doctype html>
<html ng-app="MyModule">
	<head>
		<meta charset="utf-8">
		<link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css">
	</head>
	<body>
		<div ng-controller="MyCtrl">
		<!--接下来是三个自定义的指令greeting指令-->
			<greeting greet="sayHello(name)"></greeting>
			<greeting greet="sayHello(name)"></greeting>
			<greeting greet="sayHello(name)"></greeting>
		</div>
	</body>
	<script src="framework/angular-1.3.0.14/angular.js"></script>
	<script src="ScopeAnd.js"></script>
</html>
其中定义了三个指令greeting, 每一个指令都需要调用controller中的一个sayHello方法,( angularjs中如何实现控制器和指令之间交互 指出了可以通过定义属性的方式使得控制器和指令之间进行交互,不过这里我们可以通过简单的&完成同样的功能)并且传入不同的参数name值:

var myModule = angular.module("MyModule", []);
//为控制器指定了一个sayHello方法,同时为这个方法可以传入一个参数
myModule.controller('MyCtrl', ['$scope', function($scope){
	$scope.sayHello=function(name){
		alert("Hello "+name);
	}
}])
myModule.directive("greeting", function() {
    return {
    	restrict:'AE',
        scope:{
        	greet:'&'//传递一个来自父scope的函数用于稍后调用,获取greet参数,得到sayHello(name)函数
        },
        //在template中我们在ng-click中指定一个参数,其指定方式为调用controller中greet方法,传入的参数name值为username
        //也就是ng-model='userName'中指定的参数
        template:'<input type="text" ng-model="userName" /><br/>'+
        		 '<button class="btn btn-default" ng-click="greet({name:userName})">Greeting</button><br/>'
    }
});
通过&就可以完成对父级作用方法的调用,而不是采用传统的通过 为指令指定属性的方式完成控制器和指令之间的通行!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值