template-syntax review is half way@line 1228

This commit is contained in:
Zhimin(Rex) YE 2016-05-31 22:50:33 +01:00
parent 7cb918a800
commit 9ec2bbb8ae
1 changed files with 51 additions and 42 deletions

View File

@ -87,7 +87,7 @@ code-example(language="html" escape="html").
Some legal HTML doesnt make much sense in a template. The `<html>`, `<body>`, and `<base>` elements have no useful role in our repertoire. Pretty much everything else is fair game. Some legal HTML doesnt make much sense in a template. The `<html>`, `<body>`, and `<base>` elements have no useful role in our repertoire. Pretty much everything else is fair game.
在模板中有些合法的HTML没有理由被用在一个模板中。`<html>`、`<body>`和`<base>`元素在我们的舞台上中并没有扮演有用的角色。基本上所有其它的元素都被平等使用。 在模板中有些合法的HTML没有理由被用在一个模板中。`<html>`、`<body>`和`<base>`元素在我们的舞台上中并没有扮演有用的角色。基本上所有其它的元素都被一样使用。
We can extend the HTML vocabulary of our templates with components and directives that appear as new elements and attributes. And we are about to learn how to get and set DOM values dynamically through data binding. We can extend the HTML vocabulary of our templates with components and directives that appear as new elements and attributes. And we are about to learn how to get and set DOM values dynamically through data binding.
@ -140,8 +140,8 @@ code-example(language="html" escape="html").
But it is not literally true. Interpolation is a special syntax that Angular converts into a But it is not literally true. Interpolation is a special syntax that Angular converts into a
[property binding](#property-binding), as we'll explain below. [property binding](#property-binding), as we'll explain below.
表面上看,我们在元素标签之间插入了结果或者对标签的属性进行了赋值。 表面上看,我们在元素标签之间插入了结果对标签的属性进行了赋值。
这样思考起来很方便,并且很少给我们带来错误 这样思考起来很方便,并且这个错误很少给我们带来麻烦
但严格来讲这是不对的。插值表达式是一个特殊的语法Angular把它转换成了一个[属性绑定](#property-binding),我们后面将会解释这一点。 但严格来讲这是不对的。插值表达式是一个特殊的语法Angular把它转换成了一个[属性绑定](#property-binding),我们后面将会解释这一点。
But first, let's take a closer look at template expressions and statements. But first, let's take a closer look at template expressions and statements.
@ -169,12 +169,13 @@ code-example(language="html" escape="html").
We write template expressions in a language that looks like #{_JavaScript}. We write template expressions in a language that looks like #{_JavaScript}.
Many #{_JavaScript} expressions are legal template expressions, but not all. Many #{_JavaScript} expressions are legal template expressions, but not all.
#{_JavaScript} expressions that have or promote side effects are prohibited,
including:
我们用来写模板表达式的是一种看起来很像JavaScript的语言。 我们用来写模板表达式的是一种看起来很像JavaScript的语言。
很多JavaScript表达式也是合法的模板表达式但不是全部。 很多JavaScript表达式也是合法的模板表达式但不是全部。
#{_JavaScript} expressions that have or promote side effects are prohibited,
including:
JavaScript中那些具有或可能引发副作用的表达式是被禁止的包括 JavaScript中那些具有或可能引发副作用的表达式是被禁止的包括
* assignments (`=`, `+=`, `-=`, ...) * assignments (`=`, `+=`, `-=`, ...)
@ -200,6 +201,8 @@ block notable-differences
h3#expression-context Expression context h3#expression-context Expression context
h3#expression-context 表达式上下文
block template-expressions-cannot block template-expressions-cannot
:marked :marked
Perhaps more surprising, template expressions cannot refer to anything in Perhaps more surprising, template expressions cannot refer to anything in
@ -255,7 +258,7 @@ block template-expressions-cannot
The only exceptions to these guidelines should be in specific circumstances that you thoroughly understand. The only exceptions to these guidelines should be in specific circumstances that you thoroughly understand.
这些指南中唯一的例外应该出现在那些你确信自己已经彻底理解的特定场景中。 超出上面指南外的情况应该只出现在那些你确信自己已经彻底理解的特定场景中。
#### No visible side effects #### No visible side effects
#### 没有可见的副作用 #### 没有可见的副作用
@ -271,7 +274,7 @@ block template-expressions-cannot
这条规则是Angular“单向数据流”策略的基础。 这条规则是Angular“单向数据流”策略的基础。
我们永远不应该担心读取一个组件值可能改变另外的显示值。 我们永远不应该担心读取一个组件值可能改变另外的显示值。
只要经过一遍渲染,视图就应该趋于稳定 在一次单独的渲染过程中,视图应该总是稳定的
#### Quick execution #### Quick execution
#### 执行迅速 #### 执行迅速
@ -339,8 +342,8 @@ block template-expressions-cannot
There would be no point to responding to an event otherwise. There would be no point to responding to an event otherwise.
模板语句*有副作用*。 模板语句*有副作用*。
个副作用就是我们从用户的输入更新应用状态的方式 这就是我们如何从用户的输入更新应用状态。
如果不是这样,我们就没办法响应一个事件 不然,就没有什么意义来响应一个事件了
.l-sub-section .l-sub-section
:marked :marked
@ -356,7 +359,7 @@ block template-expressions-cannot
(with !{__chaining_op}). (with !{__chaining_op}).
和模板表达式一样,模板*语句*也是一个一个看起来很像JavaScript的语言。 和模板表达式一样,模板*语句*也是一个一个看起来很像JavaScript的语言。
模板语句解析器和模板表达式解析器有所不同,它的特别之处在于它既支持支持基本赋值(`=`)又支持使用分号(`;`)和逗号(`,`)把表达式串起来。 模板语句解析器和模板表达式解析器有所不同,它的特别之处在于它既支持基本赋值(`=`)又支持使用分号(`;`)和逗号(`,`)把表达式串起来。
However, certain #{_JavaScript} syntax is not allowed: However, certain #{_JavaScript} syntax is not allowed:
@ -379,13 +382,15 @@ block template-expressions-cannot
As with expressions, statements can refer only to what's in the statement context — typically the As with expressions, statements can refer only to what's in the statement context — typically the
**component instance** to which we're binding the event. **component instance** to which we're binding the event.
和表达式中一样,语句只能引用语句上下文中 —— 典型的就是我们正在绑定事件的那个**组件的实例** —— 中的内容。 和表达式中一样,语句只能引用语句上下文中 —— 典型的就是我们正在绑定事件的那个**组件的实例**中的内容。
block statement-context block statement-context
:marked :marked
Template statements cannot refer to anything in the global namespace. They Template statements cannot refer to anything in the global namespace. They
cant refer to `window` or `document`. They cant call `console.log` or cant refer to `window` or `document`. They cant call `console.log` or
`Math.max`. `Math.max`.
模板语句无法引用全局命名控件的任何东西。它们不能引用`window`或者`document`。它们不能调用`console.log`或者`Math.max`。
:marked :marked
The *onSave* in `(click)="onSave()"` is sure to be a method of the data-bound component instance. The *onSave* in `(click)="onSave()"` is sure to be a method of the data-bound component instance.
@ -424,15 +429,15 @@ block statement-context
the application is easier to write, read, and maintain if we turn these chores over to a binding framework. the application is easier to write, read, and maintain if we turn these chores over to a binding framework.
We simply declare bindings between binding sources and target HTML elements and let the framework do the work. We simply declare bindings between binding sources and target HTML elements and let the framework do the work.
数据绑定是一种机制,用来协调用户所见与应用数据的值。 数据绑定是一种机制,用来协调用户所见和应用程序的数据值。
虽然我们能往HTML推送值或者从HTML拉取值但如果我们能把这些琐事放进数据绑定框架应用就会更容易写、读以及维护。 虽然我们能往HTML推送值或者从HTML拉取值如果我们能把这些琐事放进数据绑定框架,应用就会更容易写、读以及维护。
我们只要简单的在绑定源和目标HTML元素之间建立绑定框架就会完成这项工作。 我们只要简单的在绑定源和目标HTML元素之间建立绑定框架就会完成这项工作。
Angular provides many kinds of data binding, and well discuss each of them in this chapter. Angular provides many kinds of data binding, and well discuss each of them in this chapter.
First we'll take a high-level view of Angular data binding and its syntax. First we'll take a high-level view of Angular data binding and its syntax.
Angular提供很多种数据绑定我们将在本章中逐一讨论它们。 Angular提供很多种数据绑定我们将在本章中逐一讨论它们。
首先我们来看看Angular数据绑定的高层视角及其语法。 首先,我们从高层视角来看看Angular数据绑定和它的语法。
We can group all bindings into three categories by the direction in which data flows. We can group all bindings into three categories by the direction in which data flows.
Each category has its distinctive syntax: Each category has its distinctive syntax:
@ -467,7 +472,7 @@ table
p Interpolation p Interpolation
p 插值表达式 p 插值表达式
p Property p Property
p 属性 p Property
p Attribute p Attribute
p Attribute p Attribute
p Class p Class
@ -546,12 +551,12 @@ table
:marked :marked
We still create a structure and initialize attribute values this way in Angular templates. We still create a structure and initialize attribute values this way in Angular templates.
我们还创建了一种结构并在Angular模板中用这种方式初始化Attribute值。 在Angular模板中我们使用同样的方法来创建一个模板结构和初始化Attribute值。
Then we learn to create new elements with components that encapsulate HTML Then we learn to create new elements with components that encapsulate HTML
and drop them into our templates as if they were native HTML elements. and drop them into our templates as if they were native HTML elements.
然后我们学着用包含HTML的组件创建新元素如果把它扔进我们的模板它就和原生的HTML元素一般无二 然后我们学着用包含HTML模板的组件创建新元素并把它们当作原生HTML元素在模板中使用
+makeExample('template-syntax/ts/app/app.component.html', 'hero-detail-1')(format=".") +makeExample('template-syntax/ts/app/app.component.html', 'hero-detail-1')(format=".")
:marked :marked
Thats HTML Plus. Thats HTML Plus.
@ -575,7 +580,7 @@ table
In fact, once we start data binding, we are no longer working with HTML *attributes*. We aren't setting attributes. In fact, once we start data binding, we are no longer working with HTML *attributes*. We aren't setting attributes.
We are setting the *properties* of DOM elements, components, and directives. We are setting the *properties* of DOM elements, components, and directives.
但我们的直觉是错的!以前的思维模型在误导我们。 但我们的直觉是错的!我们的日常HTML思维模式在误导我们。
实际上一旦我们开始数据绑定我们就不再跟Attribute打交道了。我们并不是在设置Attribute 实际上一旦我们开始数据绑定我们就不再跟Attribute打交道了。我们并不是在设置Attribute
而是在设置DOM元素、组件和指令的Property。 而是在设置DOM元素、组件和指令的Property。
@ -606,7 +611,7 @@ table
* Many HTML attributes appear to map to properties ... but not in the way we might think! * Many HTML attributes appear to map to properties ... but not in the way we might think!
* 大量HTML Attribute看起来映射到了Property…… 但却不像我们自以为的那样! * 大量HTML Attribute看起来映射到了Property…… 但却不像我们想象的那样!
That last category can be especially confusing ... until we understand this general rule: That last category can be especially confusing ... until we understand this general rule:
@ -628,7 +633,7 @@ table
当用户在输入框中输入 “Sally” 时DOM元素的`value` *Property* 变成了“Sally”。 当用户在输入框中输入 “Sally” 时DOM元素的`value` *Property* 变成了“Sally”。
但是这个HTML`value` *Attribute* 保持不变。 但是这个HTML`value` *Attribute* 保持不变。
如果我们通过`input.getAttribute('value') // returns "Bob"`语句获取这个input元素的Attribute就会明白这一点。 如果我们通过`input.getAttribute('value') // 返回 "Bob"`语句获取这个input元素的Attribute就会明白这一点。
The HTML attribute `value` specifies the *initial* value; the DOM `value` property is the *current* value. The HTML attribute `value` specifies the *initial* value; the DOM `value` property is the *current* value.
@ -772,12 +777,12 @@ table
:marked :marked
Lets descend from the architectural clouds and look at each of these binding types in concrete detail. Lets descend from the architectural clouds and look at each of these binding types in concrete detail.
让我们从云端视角降下来,看看每种绑定类型的具体情况。 让我们从结构性云层中走出来,看看每种绑定类型的具体情况。
.l-main-section .l-main-section
:marked :marked
## Property binding ## Property binding
## 属性(Property)绑定 ## 属性绑定
We write a template **property binding** when we want to set a property of a view element to the value of We write a template **property binding** when we want to set a property of a view element to the value of
a [template expression](#template-expressions). a [template expression](#template-expressions).
@ -786,8 +791,8 @@ table
The most common property binding sets an element property to a component property value. An example is The most common property binding sets an element property to a component property value. An example is
binding the `src` property of an image element to a components `heroImageUrl` property: binding the `src` property of an image element to a components `heroImageUrl` property:
这种最常用的属性绑定会把元素的属性设置为组件中属性的值。 最常用的属性绑定是把元素的属性设置为组件中属性的值。
下面这个例子中,会把image元素的`src`属性绑定到组件的`heroImageUrl`属性上: 下面这个例子中image元素的`src`属性会被绑定到组件的`heroImageUrl`属性上:
+makeExample('template-syntax/ts/app/app.component.html', 'property-binding-1')(format=".") +makeExample('template-syntax/ts/app/app.component.html', 'property-binding-1')(format=".")
:marked :marked
Another example is disabling a button when the component says that it `isUnchanged`: Another example is disabling a button when the component says that it `isUnchanged`:
@ -845,7 +850,7 @@ table
### 绑定目标 ### 绑定目标
An element property between enclosing square brackets identifies the target property. The target property in the following code is the image elements `src` property. An element property between enclosing square brackets identifies the target property. The target property in the following code is the image elements `src` property.
包裹在方括号中的元素属性名用于标记出目标属性。下列代码中的目标属性是image元素的`src`属性。 包裹在方括号中的元素属性名标记着目标属性。下列代码中的目标属性是image元素的`src`属性。
+makeExample('template-syntax/ts/app/app.component.html', 'property-binding-1')(format=".") +makeExample('template-syntax/ts/app/app.component.html', 'property-binding-1')(format=".")
:marked :marked
@ -856,7 +861,7 @@ table
:marked :marked
The target name is always the name of a property, even when it appears to be the name of something else. We see `src` and may think its the name of an attribute. No. Its the name of an image element property. The target name is always the name of a property, even when it appears to be the name of something else. We see `src` and may think its the name of an attribute. No. Its the name of an image element property.
目标名总是属性的名字。即使它看起来和别的名字一样。我们看到`src`时可能会把它当做Attribute。不它不是它是image元素的属性名。 目标总是属性的名字。即使它看起来和别的名字一样。我们看到`src`时可能会把它当做Attribute。不它不是它是image元素的属性名。
Element properties may be the more common targets, Element properties may be the more common targets,
but Angular looks first to see if the name is a property of a known directive, but Angular looks first to see if the name is a property of a known directive,
@ -871,8 +876,8 @@ table
one of the property names listed in the directives `inputs` array or a property decorated with `@Input()`. one of the property names listed in the directives `inputs` array or a property decorated with `@Input()`.
Such inputs map to the directives own properties. Such inputs map to the directives own properties.
从技术的角度看Angular正在匹配一个[input](#inputs-outputs)指令的名字。这个名字是指令的`inputs`数组中所列的名字之一,或者是一个带有`@Input()`装饰器的属性。 从技术的角度看Angular正在匹配一个指令的[input](#inputs-outputs)的名字。这个名字是指令的`inputs`数组中所列的名字之一,或者是一个带有`@Input()`装饰器的属性。
inputs被映射到了指令自己的属性。 样的inputs被映射到了指令自己的属性。
:marked :marked
If the name fails to match a property of a known directive or element, Angular reports an “unknown directive” error. If the name fails to match a property of a known directive or element, Angular reports an “unknown directive” error.
@ -893,7 +898,7 @@ table
表达式中可以调用像`getFoo()`这样的方法。只有我们才知道`getFoo()`干了什么。 表达式中可以调用像`getFoo()`这样的方法。只有我们才知道`getFoo()`干了什么。
如果`getFoo()`改变了什么而我们把它绑定在什么地方我们就可能把自己坑了。Angular可能显示也可能不显示变化后的值。Angular还可能检测到变化并抛出一个警告型错误。 如果`getFoo()`改变了什么而我们把它绑定在什么地方我们就可能把自己坑了。Angular可能显示也可能不显示变化后的值。Angular还可能检测到变化并抛出一个警告型错误。
更具普遍性的建议是:盯紧数据源的属性和方法,确保它们只返回值而不做别的 更具普遍性的建议是:只使用数据属性和那些只返回值而不做其他事情的方法
### Return the proper type ### Return the proper type
### 返回恰当的类型 ### 返回恰当的类型
@ -917,13 +922,13 @@ block dart-type-exceptions
:marked :marked
### Remember the brackets ### Remember the brackets
### 别忘了括号 ### 别忘了括号
The brackets tell Angular to evaluate the template expression. The brackets tell Angular to evaluate the template expression.
If we forget the brackets, Angular treats the string as a constant and *initializes the target property* with that string. If we forget the brackets, Angular treats the string as a constant and *initializes the target property* with that string.
It does *not* evaluate the string! It does *not* evaluate the string!
括号会告诉Angular计算模板表达式。 括号会告诉Angular计算模板表达式。
如果我们忘了括号Angular就会把这个表达式当做一个字符串常量看待并且用*初始化目标属性*。 如果我们忘了括号Angular就会把这个表达式当做一个字符串常量看待并且用该字符串来*初始化目标属性*。
它*不会*计算这个字符串。 它*不会*计算这个字符串。
Don't make the following mistake: Don't make the following mistake:
@ -953,7 +958,7 @@ a(id="one-time-initialization")
The following example initializes the `prefix` property of the `HeroDetailComponent` to a fixed string, The following example initializes the `prefix` property of the `HeroDetailComponent` to a fixed string,
not a template expression. Angular sets it and forgets about it. not a template expression. Angular sets it and forgets about it.
我们像在标准HTML中一样用这种方式初始化Attribute它在初始化指令和组件的属性时也同样工作得很好 我们经常这样在标准HTML中用这种方式初始化Attribute并且这种方式也可以用在初始化指令和组件的属性
下面这个例子把`HeroDetailComponent`的`prefix`属性初始化成了一个固定的字符串而不是模板表达式。Angular设置它然后忘记它。 下面这个例子把`HeroDetailComponent`的`prefix`属性初始化成了一个固定的字符串而不是模板表达式。Angular设置它然后忘记它。
// #enddocregion property-binding-12 // #enddocregion property-binding-12
+makeExample('template-syntax/ts/app/app.component.html', 'property-binding-7')(format=".") +makeExample('template-syntax/ts/app/app.component.html', 'property-binding-7')(format=".")
@ -982,7 +987,7 @@ a(id="one-time-initialization")
没有技术上的理由能决定哪种形式更好。 没有技术上的理由能决定哪种形式更好。
我们倾向于可读性,所以倾向于插值表达式。 我们倾向于可读性,所以倾向于插值表达式。
我们建议建立组织级的代码风格规定,然后选择一种形式,既能遵循规则,又能让手头的任务做起来更自然。 我们建议建立组织级的代码风格规定,然后选择一种形式,既能遵循规则,又能让手头的任务做起来更自然。
.l-main-section .l-main-section
:marked :marked
@ -1056,7 +1061,7 @@ code-example(format="nocode").
value, using an expression that resolves to a string. value, using an expression that resolves to a string.
Attribute绑定在语法上类似于属性绑定。 Attribute绑定在语法上类似于属性绑定。
但括号中的部分不是一个元素的属性名,而是由一个**`attr`**前缀,紧跟着一个点(`.`再跟着Attribute的名字组成。 括号中的部分不是一个元素的属性名,而是由一个**`attr`**前缀,紧跟着一个点(`.`再跟着Attribute的名字组成。
我们可以通过一个能求值为字符串的表达式来设置Attribute的值。 我们可以通过一个能求值为字符串的表达式来设置Attribute的值。
Here we bind `[attr.colspan]` to a calculated value: Here we bind `[attr.colspan]` to a calculated value:
@ -1080,29 +1085,29 @@ code-example(format="nocode").
+makeExample('template-syntax/ts/app/app.component.html', 'attrib-binding-aria')(format=".") +makeExample('template-syntax/ts/app/app.component.html', 'attrib-binding-aria')(format=".")
:marked :marked
### Class binding ### Class binding
### 类绑定 ### CSS类绑定
We can add and remove CSS class names from an elements `class` attribute with We can add and remove CSS class names from an elements `class` attribute with
a **class binding**. a **class binding**.
借助**类绑定**,我们可以从元素的`class` Attribute上添加和移除CSS类名。 借助**CSS类绑定**,我们可以从元素的`class`Attribute上添加和移除CSS类名。
Class binding syntax resembles property binding. Class binding syntax resembles property binding.
Instead of an element property between brackets, we start with the prefix `class`, Instead of an element property between brackets, we start with the prefix `class`,
optionally followed by a dot (`.`) and the name of a CSS class: `[class.class-name]`. optionally followed by a dot (`.`) and the name of a CSS class: `[class.class-name]`.
类绑定在语法上类似于属性绑定。但括号中的部分不是一个元素的属性名,而是包括一个**`class`**前缀,紧跟着一个点(`.`再跟着CSS类的名字组成。 CSS类绑定在语法上类似于属性绑定。但括号中的部分不是一个元素的属性名,而是包括一个**`class`**前缀,紧跟着一个点(`.`再跟着CSS类的名字组成。
其中后两部分是可选的。形如:`[class.class-name]`。 其中后两部分是可选的。形如:`[class.class-name]`。
The following examples show how to add and remove the application's "special" class The following examples show how to add and remove the application's "special" class
with class bindings. Here's how we set the attribute without binding: with class bindings. Here's how we set the attribute without binding:
下列例子示范了如何通过类绑定来添加和移除应用的"special"类。不用绑定直接设置Attribute时是这样的 下列例子示范了如何通过CSS类绑定来添加和移除应用的"special"类。不用绑定直接设置Attribute时是这样的
+makeExample('template-syntax/ts/app/app.component.html', 'class-binding-1')(format=".") +makeExample('template-syntax/ts/app/app.component.html', 'class-binding-1')(format=".")
:marked :marked
We can replace that with a binding to a string of the desired class names; this is an all-or-nothing, replacement binding. We can replace that with a binding to a string of the desired class names; this is an all-or-nothing, replacement binding.
我们可以把它改写为一个绑定到所需类名的绑定这是一个或者全有或者全无的替换型绑定译注即当badCurly有值时class这个Attribute设置的内容会被完全覆盖 我们可以把它改写为一个绑定到所需CSS类名的绑定这是一个或者全有或者全无的替换型绑定译注即当badCurly有值时class这个Attribute设置的内容会被完全覆盖
+makeExample('template-syntax/ts/app/app.component.html', 'class-binding-2')(format=".") +makeExample('template-syntax/ts/app/app.component.html', 'class-binding-2')(format=".")
block dart-class-binding-bug block dart-class-binding-bug
@ -1136,7 +1141,7 @@ block dart-class-binding-bug
Instead of an element property between brackets, we start with the prefix `style`, Instead of an element property between brackets, we start with the prefix `style`,
followed by a dot (`.`) and the name of a CSS style property: `[style.style-property]`. followed by a dot (`.`) and the name of a CSS style property: `[style.style-property]`.
样式绑定在语法上类似于属性绑定。但括号中的部分不是一个元素的属性名,而是包括一个**`style`**前缀,紧跟着一个点(`.`再跟着CSS样式的属性名。 样式绑定在语法上类似于属性绑定。但括号中的部分不是一个元素的属性名,而是包括一个**`style`**前缀,紧跟着一个点(`.`再跟着CSS样式的属性名。
形如:`[style.style-property]`。 形如:`[style.style-property]`。
+makeExample('template-syntax/ts/app/app.component.html', 'style-binding-1')(format=".") +makeExample('template-syntax/ts/app/app.component.html', 'style-binding-1')(format=".")
@ -1158,6 +1163,9 @@ block dart-class-binding-bug
Note that a _style property_ name can be written in either Note that a _style property_ name can be written in either
[dash-case](glossary.html#dash-case), as shown above, or [dash-case](glossary.html#dash-case), as shown above, or
[camelCase](glossary.html#camelcase), such as `fontSize`. [camelCase](glossary.html#camelcase), such as `fontSize`.
注意一个_样式属性_命名方法可以用[中线命名法](glossary.html#dash-case),像上面的一样
也可以用[驼峰式命名法](glossary.html#camelcase),比如`fontSize`。
block style-property-name-dart-diff block style-property-name-dart-diff
//- N/A //- N/A
@ -1217,6 +1225,7 @@ block style-property-name-dart-diff
The `myClick` directive is further described below in the section The `myClick` directive is further described below in the section
on [Aliasing input/output properties](#aliasing-io). on [Aliasing input/output properties](#aliasing-io).
[别名input/output属性](#aliasing-io)章节有更多关于该`myClick`指令的解释。
:marked :marked
If the name fails to match an element event or an output property of a known directive, If the name fails to match an element event or an output property of a known directive,
Angular reports an “unknown directive” error. Angular reports an “unknown directive” error.