AngularJS的一些指令会创建子作用域,而子作用域会继承自父作用域,大致可分为以下3种

1、创建子作用域并继承父作用域的指令

  • ng-repeat
  • ng-include
  • ng-switch
  • ng-controller
  • directive(scope:true)
  • directive(transclude:true)
2、创建子作用域但不继承父作用域
  • directive(scope:{...})
3、不创建作用域
  • directive(scope:false)
AngularJS的作用域继承是从上到下继承的,而且这种继承机制是和javascript继承一样的。如果子作用域继承了父作用域的一个基本类型的属性,那么子作用域修改这个基本类型属性将不会同步到父作用域,而是在子作用域中添加一个该属性一样名称的属性,这个属性会覆盖父类的同名属性;如果子作用域继承了父作用域的一个属性,这个属性的值是一个对象,那么子类在修改这个对象的时候就会按照原型链的方法去寻找这个属性,修改子类的该对象的值也会同步到父类,这是javascript一样的,因为继承的是对象的引用。
下面这个例子列举该种情况
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<title>AngularJS</title>
</head>
<body>
<div ng-controller="parent">
parent-base:<input type="text" ng-model="base" />
parent-obj:<input type="text" ng-model="obj.name">
<div ng-controller="child">
child-base:<input type="text" ng-model="base" />
child-obj:<input type="text" ng-model="obj.name"/>
</div>
</div>
</body>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript">
var app = angular.module("myApp", []);
app.controller("parent", function(){})
.controller("child", function(){});
</script>
</html>

在这个例子中,如果绑定的是对象的值,则父、子作用域可以相互影响,而如果绑定的是基本类型的值,则一旦改变child-base输入框的值,则就会在child的scope创建一个base属性,这个属性会覆盖parent的base,则父、子就不会相互影响了。为避免这种情况,强烈推荐使用.的对象形式绑定值。


ng-include和ng-switch和上面的ng-controller差不多,ng-repeat和这3个指令不同,它会对生成的每一项都创建一个子作用域,且这些子作用域都继承自一个父作用域。
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<title>AngularJS</title>
</head>
<body>
<div ng-controller="parent">
<div>
arr:{{arr[0]}}
</div>
<ul ng-repeat = "age in arr">
<li>
<input ng-model="age">
</li>
</ul>
<div>
obj-arr:{{obj[0].age}}
</div>
<ul ng-repeat = "age in obj">
<li>
<input ng-model="age.age">
</li>
</ul>
</div>
</body>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript">
var app = angular.module("myApp", []);
app.controller("parent", function($scope){
$scope.arr = [1,2];
$scope.obj = [{age:1},{age:2}];
}); </script>
</html>

运行代码之后可以知道,ng-repeat会为每一项创建一个子作用域,它用age来遍历数组,然后子作用域会创建一个用age做属性名的属性,如果age是基本类型,则改变age不会同步到父作用域,如果是对象,则父作用域也会跟着改变。


下面是directive中scope设置不同值时的情况。
当scope=false时,这时自定义没有产生新的作用域,仍旧使用controller的作用域,从运行结果可知,虽然我们设置的name是一个基本类型,但是当输入框中的值改变时,显示的值也会跟着变化,这是因为它们的都是引用同一个scope。
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<title>AngularJS</title>
</head>
<body>
<div ng-controller="parent">
<div ng-bind="name"></div>
<div my-name></div>
</div>
</body>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript">
var app = angular.module("myApp", []);
app.controller("parent", function($scope){
$scope.name = "Jhon";
}).directive("myName", function(){
return {
restrict:"A",
scope:false,
template:'<input type="text" ng-model="name"/>'
}
});
</script>
</html>

当scope=true时,这个时候会产生新的作用域,并且该子作用域继承自父作用域,从下面实例,我们仍然改变输入框的值,但是显示的值并没有改变,这和上诉内置指令的原理是一样的。

<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<title>AngularJS</title>
</head>
<body>
<div ng-controller="parent">
<div ng-bind="name"></div>
<div my-name></div>
</div>
</body>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript">
var app = angular.module("myApp", []);
app.controller("parent", function($scope){
$scope.name = "Jhon";
}).directive("myName", function(){
return {
restrict:"A",
scope:true,
template:'<input type="text" ng-model="name"/>'
}
});
</script>
</html>

当scope={...}时,这时会产生一个独立的作用域,该作用域独立于任何作用域之外,不继承任何原型。但是可以通过@,=,&来和父作用域通信。

<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<title>AngularJS</title>
</head>
<body>
<div ng-controller="parent">
<div ng-bind="name"></div>
<div my-name show-name="name"></div>
</div>
</body>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript">
var app = angular.module("myApp", []);
app.controller("parent", function($scope){
$scope.name = "Jhon";
}).directive("myName", function(){
return {
restrict:"A",
scope:{
title:'=showName'
},
template:'<input type="text" ng-model="title"/>'
}
});
</script>
</html>

注意:这里虽然我们使用了基本类型,但是父作用域的值还是会随着输入框的改变而改变,这与其它的继承不同。


虽然独立作用域没有继承任何原型,但我们还是能够使用$parent.
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<title>AngularJS</title>
</head>
<body>
<div ng-controller="parent">
<div ng-bind="name"></div>
<div my-name></div>
</div>
</body>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript">
var app = angular.module("myApp", []);
app.controller("parent", function($scope){
$scope.name = "Jhon";
}).directive("myName", function(){
return {
restrict:"A",
scope:{ },
template:'<input type="text" ng-model="$parent.name"/>'
}
});
</script>
</html>

当transclude=true时,transclude会创建自己的作用域,这个作用域继承了自定义指令外的作用域,所以下例输出mery,Jhon。

<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<title>AngularJS</title>
</head>
<body>
<div ng-controller="parent">
<my-name>
<span>{{name}}</span>
</my-name>
</div>
</body>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript">
var app = angular.module("myApp", []);
app.controller("parent", function($scope){
$scope.name = "Jhon";
}).directive("myName", function(){
return {
restrict:"EA",
transclude:true,
scope:{ },
template:'<div>{{name}}</div><div ng-transclude></div>',
link: function(scope){
scope.name = "mery";
}
}
});
</script>
</html>








angular之scope详解的更多相关文章

  1. angular 自定义指令详解 Directive

    在angular中,Directive,自定义指令的学习,可以更好的理解angular指令的原理,当angular的指令不能满足你的需求的时候,嘿嘿,你就可以来看看这篇文章,自定义自己的指令,可以满足 ...

  2. 【转】angular中$parse详解教程

    原文: https://yq.aliyun.com/ziliao/40516 ------------------------------------------------------------- ...

  3. Maven依赖中的scope详解,在eclipse里面用maven install可以编程成功,到服务器上用命令执行报VM crash错误

    Maven依赖中的scope详解 项目中用了<scope>test</scope>在eclipse里面用maven install可以编译成功,到服务器上用命令执行报VM cr ...

  4. Angular 6.X CLI(Angular.json) 属性详解

    Angular CLI(Angular.json) 属性详解 简介 angular cli 是angular commond line interface的缩写,意为angular的命令行接口.在an ...

  5. spring中的scope详解

    spring容器中的bean默认是单例模式的,改成非单例模式需要在类上加上@Scope("prototype") 1. scope概论 spring中scope是一个非常关键的概念 ...

  6. angular $q promise详解

    前言 通过本文,你大概能清楚angular promise是个啥,$q又是个啥,以及怎么用它.这里咱们先灌输下promise的思想. 下面写的全是废话,一些看着高逼格其实没什么大作用的概念,想知道$q ...

  7. Angular依赖注入详解

    Angular算是将后端开发工程化引入前端的先驱之一,而Dependency injection依赖注入(后面简称为DI)又是Angular内部运作的核心功能,所以要深入理解Angular有必要先理解 ...

  8. angular自定义指令详解

    指令(directive)是angular里面最核心也是最难懂的东西,在慕课网看了下大漠穷秋老湿的视频,自己百度半天做了一些小test,总算把一切都搞明白了. 先列出学习来源: 指令中controll ...

  9. AngularJs指令配置参数scope详解

    AngularJs最重要也是最难理解的模块之一就是它的指令(directive)了,自定义指令配置有很多个参数,下面我只说说其中scope的配置极其含义. scope表示指令的作用域,它有三个可选值: ...

随机推荐

  1. [js高手之路]Node.js+jade+express+mongodb+mongoose+promise实现todolist

    promise主要是用来解决异步回调问题,其实还有好几种比promise更好的方案,后面再说,这节,我们先用promise来改造下,我以前写的一篇文章[js高手之路]javascript腾讯面试题学习 ...

  2. PHP多进程编程pcntl_fork解

    其实PHP是支持并发的,只是平时很少使用而已.平时使用最多的应该是使用PHP-FMP调度php进程了吧. 但是,PHP的使用并不局限于做Web,我们完全也可以使用PHP来进行系统工具类的编程,做监控或 ...

  3. css预处理器less和scss之sass介绍(二)

    本来打算整理jQuery Mobile来着,但是没有研究明白,所以接着上个周的继续介绍... [scss中的基础语法]   1.scss中的变量 ①声明变量:$变量名:变量值 $width:100px ...

  4. Https系列之三:让服务器同时支持http、https,基于spring boot

    Https系列会在下面几篇文章中分别作介绍: 一:https的简单介绍及SSL证书的生成二:https的SSL证书在服务器端的部署,基于tomcat,spring boot三:让服务器同时支持http ...

  5. Redis——windows环境安装redis和redis sentinel部署

    一:Redis的下载和安装 1:下载Redis Redis的官方网站Download页面,Redis提示说:Redis的正式版不支持Windows,要Windows学习Redis,请点击Learn m ...

  6. Linux vi 退出&保存/不保存

    无论是否退出 vi,均可保存所做的工作.按 ESC 键,确定 vi 是否处于命令模式. 操作   键入 保存,但不退出vi                          :w 保存并退出vi    ...

  7. ZOJ2724 Windows Message Queue 裸queue的模拟

    题目要求FIFO #include<cstdio> #include<cstdlib> #include<iostream> #include<queue&g ...

  8. Vue中之nextTick函数源码分析

    Vue中之nextTick函数源码分析 1. 什么是Vue.nextTick()?官方文档解释如下:在下次DOM更新循环结束之后执行的延迟回调.在修改数据之后立即使用这个方法,获取更新后的DOM. 2 ...

  9. SpringMVC 实现文件的上传与下载

    一  配置SpringMVC ,并导入与文件上传下载有关的jar包(在此不再赘述) 二 新建 相应 jsp 和controller FileUpAndDown.jsp <%@ page lang ...

  10. 《阿里巴巴Java开发规约》插件使用介绍

    一.简介 阿里巴巴于10月14日在杭州云栖大会上,正式发布了<阿里巴巴Java开发规约>扫描插件!该插件基于<阿里巴巴Java开发规约>手册内容,在扫描代码后,将不符合规约的代 ...