详解Angular模板引用变量及其作用域


Posted in Javascript onNovember 23, 2018

Angular模板引用变量

如果你曾经参与过Angular项目的开发,那么你可能一眼就会看出谁将是本文的主角:

<input type="text" [value]="value" #name>

若你对此陌生,也无须在意。示例代码的<input>标签的属性中存在一个画风明显与其他属性不同的家伙——#name,这种以一个#开头命名,被附加在DOM元素上的属性,被称为模板引用变量(template reference variables)。

那么何为模板引用变量呢?文档是这样描述的:

A template reference variable is often a reference to a DOM element within a template. It can also be a reference to an Angular component or directive or a web component.

模板引用变量可以是Angualr模板中的DOM元素、Angular组件(指令),甚至Web组件的引用,而它具体是什么,则取决于它所依附的元素(不使用指令进行干预时)。如前文示例代码中的模板引用变量name就是<input>这一DOM元素的引用。

既然模板引用变量是模板中某一元素的引用,那理所当然地我们便可以通过这个引用变量" 触及 "该模板元素的" 实体 "。这在实际地开发中是十分实用的,考虑以下代码:

<app-component #component [input]="variable"></app-component>
{{ component.input }}
{{ component.func() }}

通过模板引用变量我们获得了app-component组件的实例引用,这使得我们可以轻松地在模板中访问app-component组件内部的成员。在某些情境下,这种能力给我们的开发提供了很大的助力。

模板引用变量的作用域

You can refer to a template reference variable anywhere in the template.

在文档中,官方毫不含糊地向我们表示:模板引用变量可以在模板中的任何地方使用。最骚的是,“任何地方”还被特别加粗。我们在大多数的时候,并不会对这句话产生疑问,但也许某天你会怀疑这个anywhere是否真实。有如下的代码:

<app-card>
  <ng-template #body>
    <app-component #component [input]="variable"></app-component>
  </ng-template>
  <ng-template #footer>
    {{component.input}}
  </ng-template>
</app-card>

当代码运行后,我们将会在控制台看到这样的错误提示:

TypeError: Cannot read property 'input' of undefined

为什么component会是undefined?

答案其实很明显,模板引用对象可以在模板中的任何地方使用,但此例中component的定义与使用却并不在一个template中。文档中所描述的 template 并不能直接与 组件的模板文件 划上等号。当我们使用ng-template时,会在当前模板的内部再建立一个新的模板,它的内部无法直接被外部模板触及,因此示例中的component.input自然会引起错误。

当 template 的定义明确以后,一切都是如此简单:模板引用变量存在作用域,其作用域是它所处的 template,而非它所在的模板文件,同时它可以在其作用域内的任何地方被使用。

最后,我们再看一个例子:

<div *ngIf="true">
  <app-component #component [input]="variable"></app-component>
</div>
{{component.input}}

当这段代码运行后,我们依旧会在控制台看到:

TypeError: Cannot read property 'input' of undefined

至于背后的原因,我便作为小小的悬念留给大家,由大家自己去了解。以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 简单抽屉效果的实现代码
Mar 09 Javascript
javascript中关于执行环境的杂谈
Aug 14 Javascript
JS实现可改变列宽的table实例
Jul 02 Javascript
不使用jquery实现js打字效果示例分享
Jan 19 Javascript
使用AngularJS处理单选框和复选框的简单方法
Jun 19 Javascript
JavaScript动态生成二维码图片
Apr 20 Javascript
基于angular中的重要指令详解($eval,$parse和$compile)
Oct 21 Javascript
AngularJS使用带属性值的ng-app指令实现自定义模块自动加载的方法
Jan 04 Javascript
vue 中自定义指令改变data中的值
Jun 02 Javascript
Angular入口组件(entry component)与声明式组件的区别详解
Apr 09 Javascript
微信小程序HTTP接口请求封装的实现
Feb 21 Javascript
vue实现select下拉显示隐藏功能
Sep 30 Javascript
vue使用better-scroll实现下拉刷新、上拉加载
Nov 23 #Javascript
详解Vue2.0组件的继承与扩展
Nov 23 #Javascript
angular4自定义表单控件[(ngModel)]的实现
Nov 23 #Javascript
详解Angular中实现自定义组件的双向绑定的两种方法
Nov 23 #Javascript
Vue.js组件间通信方式总结【推荐】
Nov 23 #Javascript
vue-cli 2.*中导入公共less文件的方法步骤
Nov 22 #Javascript
vue全局使用axios的方法实例详解
Nov 22 #Javascript
You might like
PHP屏蔽蜘蛛访问代码及常用搜索引擎的HTTP_USER_AGENT
2013/03/06 PHP
php ci框架验证码实例分析
2013/06/26 PHP
PHP中让curl支持sock5的代码实例
2015/01/21 PHP
PHP获取文件相对路径的方法
2015/02/26 PHP
Yii控制器中filter过滤器用法分析
2016/07/15 PHP
div移动 输入框不能输入的问题
2009/11/19 Javascript
一款Jquery 分页插件的改造方法(服务器端分页)
2011/07/11 Javascript
元素绑定click点击事件方法
2015/06/08 Javascript
简述JavaScript中正则表达式的使用方法
2015/06/15 Javascript
基于Jquery+div+css实现弹出登录窗口(代码超简单)
2015/10/27 Javascript
Web开发必知Javascript技巧大全
2016/02/23 Javascript
简单谈谈json跨域
2016/03/13 Javascript
jQuery插件passwordStrength密码强度指标详解
2016/06/24 Javascript
前端微信支付js代码
2016/07/25 Javascript
详解Vue使用 vue-cli 搭建项目
2017/04/20 Javascript
微信小程序学习之数据处理详解
2017/07/05 Javascript
详解从Vue.js源码看异步更新DOM策略及nextTick
2017/10/11 Javascript
说说Vue.js中的functional函数化组件的使用
2019/02/12 Javascript
微信小程序前端promise封装代码实例
2019/08/24 Javascript
vue项目打包之开发环境和部署环境的实现
2020/04/23 Javascript
vue 清空input标签 中file的值操作
2020/07/21 Javascript
vue深度监听(监听对象和数组的改变)与立即执行监听实例
2020/09/04 Javascript
[01:32]2014DOTA2西雅图邀请赛 CIS我们有信心进入正赛
2014/07/08 DOTA
Python 通过URL打开图片实例详解
2017/06/01 Python
用Python实现将一张图片分成9宫格的示例
2019/07/05 Python
Pytorch中Tensor与各种图像格式的相互转化详解
2019/12/26 Python
解决Keyerror ''acc'' KeyError: ''val_acc''问题
2020/06/18 Python
windows系统Tensorflow2.x简单安装记录(图文)
2021/01/18 Python
python中封包建立过程实例
2021/02/18 Python
美国创意礼品网站:UncommonGoods
2017/02/03 全球购物
金智子午JAVA面试题
2015/09/04 面试题
《云雀的心愿》教学反思
2014/02/25 职场文书
《鸿门宴》教学反思
2014/04/22 职场文书
运动会广播稿100字
2014/09/14 职场文书
东京审判观后感
2015/06/01 职场文书
Mysql将字符串按照指定字符分割的正确方法
2022/05/30 MySQL