mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
docs: smooth out directives guide narrative flow (#69822)
PR Close #69822
This commit is contained in:
committed by
Alex Rickabaugh
parent
433276b12d
commit
fe35cbd320
@@ -1,38 +1,95 @@
|
||||
# Attribute directives
|
||||
|
||||
Change the appearance or behavior of DOM elements and Angular components with attribute directives.
|
||||
Attribute directives change the appearance or behavior of DOM elements and Angular components.
|
||||
|
||||
## Built-in attribute directives
|
||||
|
||||
Angular includes several built-in attribute directives for common tasks:
|
||||
|
||||
| Common directives | Details |
|
||||
| :----------------------------------------------------- | :------------------------------------------------- |
|
||||
| [`NgClass`](#adding-and-removing-classes-with-ngclass) | Adds and removes a set of CSS classes. |
|
||||
| [`NgStyle`](#setting-inline-styles-with-ngstyle) | Adds and removes a set of HTML styles. |
|
||||
| [`NgModel`](guide/forms/template-driven-forms) | Adds two-way data binding to an HTML form element. |
|
||||
|
||||
HELPFUL: Built-in directives use only public APIs. They do not have special access to any private APIs that other directives can't access.
|
||||
|
||||
### Adding and removing classes with `NgClass`
|
||||
|
||||
Add or remove multiple CSS classes simultaneously by binding `[ngClass]` to an expression. To use `NgClass`, add it to the component's `imports` list:
|
||||
|
||||
```angular-ts
|
||||
import {NgClass} from '@angular/common';
|
||||
|
||||
@Component({
|
||||
/* ... */
|
||||
imports: [NgClass],
|
||||
})
|
||||
export class AppComponent {}
|
||||
```
|
||||
|
||||
To toggle a single class, bind `[ngClass]` to a conditional expression that returns the class name. In this example, `ngClass` applies the `special` class when `isSpecial` is `true`:
|
||||
|
||||
<docs-code header="app.component.html" path="adev/src/content/examples/built-in-directives/src/app/app.component.html" region="special-div"/>
|
||||
|
||||
To toggle several classes at once, bind `[ngClass]` to an object. Each key is a class name, and Angular adds the class when its value is truthy and removes it when its value is falsy:
|
||||
|
||||
```angular-html
|
||||
<div [ngClass]="{'saveable': canSave, 'modified': !isUnchanged, 'special': isSpecial}">
|
||||
This div's classes reflect the current component state.
|
||||
</div>
|
||||
```
|
||||
|
||||
HELPFUL: To add or remove a _single_ class, use [class binding](/guide/templates/binding#css-class-and-style-property-bindings) rather than `NgClass`.
|
||||
|
||||
### Setting inline styles with `NgStyle`
|
||||
|
||||
Set multiple inline styles simultaneously by binding `[ngStyle]` to an object. To use `NgStyle`, add it to the component's `imports` list:
|
||||
|
||||
```angular-ts
|
||||
import {NgStyle} from '@angular/common';
|
||||
|
||||
@Component({
|
||||
/* ... */
|
||||
imports: [NgStyle],
|
||||
})
|
||||
export class AppComponent {}
|
||||
```
|
||||
|
||||
Each key in the object is a CSS property name and each value is the style to apply:
|
||||
|
||||
```angular-html
|
||||
<div
|
||||
[ngStyle]="{
|
||||
'font-style': canSave ? 'italic' : 'normal',
|
||||
'font-weight': !isUnchanged ? 'bold' : 'normal',
|
||||
'font-size': isSpecial ? '24px' : '12px',
|
||||
}"
|
||||
>
|
||||
This div's styles reflect the current component state.
|
||||
</div>
|
||||
```
|
||||
|
||||
HELPFUL: To add or remove a _single_ style, use [style bindings](guide/templates/binding#css-class-and-style-property-bindings) rather than `NgStyle`.
|
||||
|
||||
## Building an attribute directive
|
||||
|
||||
This section walks you through creating a highlight directive that sets the background color of the host element to yellow.
|
||||
A custom attribute directive is a class with the `@Directive()` decorator. The decorator's `selector` defines the attribute that applies the directive. By convention, custom selectors use a prefix such as `app` and wrap the name in square brackets to form an attribute selector:
|
||||
|
||||
1. To create a directive, use the CLI command [`ng generate directive`](tools/cli/schematics).
|
||||
```angular-ts
|
||||
import {Directive} from '@angular/core';
|
||||
|
||||
```shell
|
||||
ng generate directive highlight
|
||||
```
|
||||
@Directive({
|
||||
selector: '[appHighlight]',
|
||||
})
|
||||
export class HighlightDirective {}
|
||||
```
|
||||
|
||||
The CLI creates `src/app/highlight.directive.ts`, a corresponding test file `src/app/highlight.directive.spec.ts`.
|
||||
HELPFUL: The CLI command [`ng generate directive`](tools/cli/schematics) scaffolds a directive along with its test file.
|
||||
|
||||
```angular-ts
|
||||
import {Directive} from '@angular/core';
|
||||
To change the host element, a directive needs a reference to it. Inject [`ElementRef`](guide/di) to reach the element through its `nativeElement` property. This directive sets the background to yellow when Angular creates it:
|
||||
|
||||
@Directive({
|
||||
selector: '[appHighlight]',
|
||||
})
|
||||
export class HighlightDirective {}
|
||||
```
|
||||
|
||||
The `@Directive()` decorator's configuration property specifies the directive's CSS attribute selector, `[appHighlight]`.
|
||||
|
||||
1. Import `ElementRef` and `inject` from `@angular/core`.
|
||||
`ElementRef` grants direct access to the host DOM element through its `nativeElement` property.
|
||||
|
||||
1. Use [`inject`](guide/di) to obtain a reference to the host DOM element, the element to which you apply `appHighlight`.
|
||||
|
||||
1. Add logic to the `HighlightDirective` class that sets the background to yellow.
|
||||
|
||||
<docs-code header="highlight.directive.ts" path="adev/src/content/examples/attribute-directives/src/app/highlight.directive.1.ts"/>
|
||||
<docs-code header="highlight.directive.ts" path="adev/src/content/examples/attribute-directives/src/app/highlight.directive.1.ts"/>
|
||||
|
||||
IMPORTANT: Directives _do not_ support namespaces.
|
||||
|
||||
@@ -42,104 +99,43 @@ IMPORTANT: Directives _do not_ support namespaces.
|
||||
|
||||
## Applying an attribute directive
|
||||
|
||||
To use the `HighlightDirective`, add a `<p>` element to the HTML template with the directive as an attribute.
|
||||
To apply the directive, add its selector as an attribute on an element:
|
||||
|
||||
<docs-code header="app.component.html" path="adev/src/content/examples/attribute-directives/src/app/app.component.1.html" region="applied"/>
|
||||
|
||||
Angular creates an instance of the `HighlightDirective` class, which uses `inject(ElementRef)` to get a reference to the `<p>` element and set its background style to yellow.
|
||||
Angular creates an instance of `HighlightDirective` for that `<p>` element, injects a reference to the element, and sets its background to yellow.
|
||||
|
||||
## Handling user events
|
||||
|
||||
This section shows you how to detect when a user mouses into or out of the element and to respond by setting or clearing the highlight color.
|
||||
|
||||
1. Configure host event bindings using the `host` property in the `@Directive()` decorator.
|
||||
|
||||
<docs-code header="src/app/highlight.directive.ts (decorator)" path="adev/src/content/examples/attribute-directives/src/app/highlight.directive.2.ts" region="decorator"/>
|
||||
|
||||
1. Add two event handler methods, and map host element events to them via the `host` property.
|
||||
|
||||
<docs-code header="highlight.directive.ts (mouse-methods)" path="adev/src/content/examples/attribute-directives/src/app/highlight.directive.2.ts" region="mouse-methods"/>
|
||||
|
||||
Subscribe to events of the DOM element that hosts an attribute directive (the `<p>` in this case) by configuring event listeners on the directive's [`host` property](guide/components/host-elements#binding-to-the-host-element).
|
||||
|
||||
HELPFUL: The handlers delegate to a helper method, `highlight()`, that sets the color on the host DOM element, `el`.
|
||||
|
||||
The complete directive is as follows:
|
||||
To respond to user interaction, bind host element events to handler methods through the `host` property of the `@Directive()` decorator. The following directive highlights the host element while the pointer is over it and clears the highlight when the pointer leaves:
|
||||
|
||||
<docs-code header="highlight.directive.ts" path="adev/src/content/examples/attribute-directives/src/app/highlight.directive.2.ts"/>
|
||||
|
||||
The background color appears when the pointer hovers over the paragraph element and disappears as the pointer moves out.
|
||||
The `host` property maps the `mouseenter` and `mouseleave` events to the `onMouseEnter()` and `onMouseLeave()` methods, which delegate to a `highlight()` helper that sets the background color on the host element. For more on host event bindings, see [binding to the host element](guide/components/host-elements#binding-to-the-host-element).
|
||||
|
||||
<img alt="Second Highlight" src="assets/images/guide/attribute-directives/highlight-directive-anim.gif">
|
||||
|
||||
## Passing values into an attribute directive
|
||||
## Accepting input values
|
||||
|
||||
This section walks you through setting the highlight color while applying the `HighlightDirective`.
|
||||
Like components, directives accept inputs through the [`input()`](guide/components/inputs) function. Give an input the same name as the selector so that a single binding both applies the directive and passes a value to it:
|
||||
|
||||
1. In `highlight.directive.ts`, import `input` from `@angular/core`.
|
||||
<docs-code header="highlight.directive.ts" path="adev/src/content/examples/attribute-directives/src/app/highlight.directive.3.ts" region="input"/>
|
||||
|
||||
<docs-code header="highlight.directive.ts (imports)" path="adev/src/content/examples/attribute-directives/src/app/highlight.directive.3.ts" region="imports"/>
|
||||
Read the input by calling its signal, and fall back to a default when no value is bound:
|
||||
|
||||
1. Add an `appHighlight` `input` property.
|
||||
<docs-code header="highlight.directive.ts" path="adev/src/content/examples/attribute-directives/src/app/highlight.directive.3.ts" region="mouse-enter"/>
|
||||
|
||||
<docs-code header="highlight.directive.ts" path="adev/src/content/examples/attribute-directives/src/app/highlight.directive.3.ts" region="input"/>
|
||||
In the template, bind the value to the selector. Because the input shares the selector's name, `[appHighlight]` both applies the directive and sets its value:
|
||||
|
||||
The `input()` function adds metadata to the class that makes the directive's `appHighlight` property available for binding.
|
||||
<docs-code header="app.component.html" path="adev/src/content/examples/attribute-directives/src/app/app.component.html" region="color"/>
|
||||
|
||||
1. In `app.component.ts`, add a `color` property to the `AppComponent`.
|
||||
A directive can declare more than one input. The following directive adds a `defaultColor` input, then falls back through `appHighlight`, `defaultColor`, and finally `red`:
|
||||
|
||||
<docs-code header="app.component.ts (class)" path="adev/src/content/examples/attribute-directives/src/app/app.component.1.ts" region="class"/>
|
||||
<docs-code header="highlight.directive.ts" path="adev/src/content/examples/attribute-directives/src/app/highlight.directive.ts"/>
|
||||
|
||||
1. To simultaneously apply the directive and the color, use property binding with the `appHighlight` directive selector, setting it equal to `color`.
|
||||
Bind both inputs on the same element. Because `defaultColor` takes a static string rather than a dynamic expression, it doesn't need square brackets:
|
||||
|
||||
<docs-code header="app.component.html (color)" path="adev/src/content/examples/attribute-directives/src/app/app.component.html" region="color"/>
|
||||
|
||||
The `[appHighlight]` attribute binding performs two tasks:
|
||||
- Applies the highlighting directive to the `<p>` element
|
||||
- Sets the directive's highlight color with a property binding
|
||||
|
||||
### Setting the value with user input
|
||||
|
||||
This section guides you through adding radio buttons to bind your color choice to the `appHighlight` directive.
|
||||
|
||||
1. Add markup to `app.component.html` for choosing a color as follows:
|
||||
|
||||
<docs-code header="app.component.html (v2)" path="adev/src/content/examples/attribute-directives/src/app/app.component.html" region="v2"/>
|
||||
|
||||
2. Revise the `AppComponent.color` so that it has no initial value.
|
||||
|
||||
<docs-code header="app.component.ts (class)" path="adev/src/content/examples/attribute-directives/src/app/app.component.ts" region="class"/>
|
||||
|
||||
3. In `highlight.directive.ts`, revise `onMouseEnter` method so that it first tries to highlight with `appHighlight` and falls back to `red` if `appHighlight` is `undefined`.
|
||||
<docs-code header="highlight.directive.ts (mouse-enter)" path="adev/src/content/examples/attribute-directives/src/app/highlight.directive.3.ts" region="mouse-enter"/>
|
||||
|
||||
4. Serve your application to verify that the user can choose the color with the radio buttons.
|
||||
|
||||
<img alt="Animated gif of the refactored highlight directive changing color according to the radio button the user selects" src="assets/images/guide/attribute-directives/highlight-directive-v2-anim.gif">
|
||||
|
||||
## Binding to a second property
|
||||
|
||||
This section guides you through configuring your application so the developer can set the default color.
|
||||
|
||||
1. Add a second `input()` property to `HighlightDirective` called `defaultColor`.
|
||||
|
||||
<docs-code header="highlight.directive.ts (defaultColor)" path="adev/src/content/examples/attribute-directives/src/app/highlight.directive.ts" region="defaultColor"/>
|
||||
|
||||
2. Revise the directive's `onMouseEnter` so that it first tries to highlight with the `appHighlight`, then with the `defaultColor`, and falls back to `red` if both properties are `undefined`.
|
||||
|
||||
<docs-code header="highlight.directive.ts (mouse-enter)" path="adev/src/content/examples/attribute-directives/src/app/highlight.directive.ts" region="mouse-enter"/>
|
||||
|
||||
3. To bind to the `AppComponent.color` and fall back to "violet" as the default color, add the following HTML.
|
||||
In this case, the `defaultColor` binding doesn't use square brackets, `[]`, because the value is a static string, not a dynamic expression.
|
||||
|
||||
<docs-code header="app.component.html (defaultColor)" path="adev/src/content/examples/attribute-directives/src/app/app.component.html" region="defaultColor"/>
|
||||
|
||||
As with components, you can add multiple directive property bindings to a host element.
|
||||
|
||||
The default color is red if there is no default color binding.
|
||||
When the user chooses a color the selected color becomes the active highlight color.
|
||||
|
||||
<img alt="Animated gif of final highlight directive that shows red color with no binding and violet with the default color set. When user selects color, the selection takes precedence." src="assets/images/guide/attribute-directives/highlight-directive-final-anim.gif">
|
||||
<docs-code header="app.component.html" path="adev/src/content/examples/attribute-directives/src/app/app.component.html" region="defaultColor"/>
|
||||
|
||||
## Deactivating Angular processing with `NgNonBindable`
|
||||
|
||||
@@ -157,3 +153,10 @@ In the following example, the `appHighlight` directive is still active but Angul
|
||||
<docs-code header="app.component.html" path="adev/src/content/examples/attribute-directives/src/app/app.component.html" region="ngNonBindable-with-directive"/>
|
||||
|
||||
If you apply `ngNonBindable` to a parent element, Angular disables interpolation and binding of any sort, such as property binding or event binding, for the element's children.
|
||||
|
||||
## What's next
|
||||
|
||||
<docs-pill-row>
|
||||
<docs-pill href="guide/directives/structural-directives" title="Structural directives"/>
|
||||
<docs-pill href="guide/directives/directive-composition-api" title="Directive composition API"/>
|
||||
</docs-pill-row>
|
||||
|
||||
@@ -1,118 +1,73 @@
|
||||
<docs-decorative-header title="Built-in directives" imgSrc="adev/src/assets/images/directives.svg"> <!-- markdownlint-disable-line -->
|
||||
Directives are classes that add additional behavior to elements in your Angular applications.
|
||||
<docs-decorative-header title="Directives" imgSrc="adev/src/assets/images/directives.svg"> <!-- markdownlint-disable-line -->
|
||||
Directives add behavior to elements and components in your Angular applications.
|
||||
</docs-decorative-header>
|
||||
|
||||
Use Angular's built-in directives to manage forms, lists, styles, and what users see.
|
||||
A directive can change how an element looks, how it behaves, or how it fits into the DOM. Angular ships with several built-in directives, and you can write your own.
|
||||
|
||||
The different types of Angular directives are as follows:
|
||||
## When to use a directive
|
||||
|
||||
| Directive Types | Details |
|
||||
| :--------------------------------------------------------------- | :-------------------------------------------------------------------------------- |
|
||||
| [Components](guide/components) | Used with a template. This type of directive is the most common directive type. |
|
||||
| [Attribute directives](#built-in-attribute-directives) | Change the appearance or behavior of an element, component, or another directive. |
|
||||
| [Structural directives](/guide/directives/structural-directives) | Change the DOM layout by adding and removing DOM elements. |
|
||||
Directives are most effective when they encapsulate **reusable** behavior that you want to apply to an existing element or component.
|
||||
|
||||
This guide covers built-in [attribute directives](#built-in-attribute-directives).
|
||||
Common examples include:
|
||||
|
||||
## Built-in attribute directives
|
||||
- Applying the same appearance or behavior across many elements, such as autofocus or a tooltip.
|
||||
- Reading from or writing to the host element's DOM, attributes, or classes.
|
||||
- Adding behavior to a component you don't own without changing its source.
|
||||
|
||||
Attribute directives listen to and modify the behavior of other HTML elements, attributes, properties, and components.
|
||||
If you need to render your own markup or manage a piece of UI with its own template, reach for a [component](guide/components) rather than a directive.
|
||||
|
||||
The most common attribute directives are as follows:
|
||||
## A quick example
|
||||
|
||||
| Common directives | Details |
|
||||
| :----------------------------------------------------- | :------------------------------------------------- |
|
||||
| [`NgClass`](#adding-and-removing-classes-with-ngclass) | Adds and removes a set of CSS classes. |
|
||||
| [`NgStyle`](#setting-inline-styles-with-ngstyle) | Adds and removes a set of HTML styles. |
|
||||
| [`NgModel`](guide/forms/template-driven-forms) | Adds two-way data binding to an HTML form element. |
|
||||
Suppose you want elements to highlight when the user hovers over them, changing their background color to yellow. Rather than repeat the same event-handling logic on every element, you can package that behavior in a directive and apply it wherever you need it.
|
||||
|
||||
HELPFUL: Built-in directives use only public APIs. They do not have special access to any private APIs that other directives can't access.
|
||||
|
||||
## Adding and removing classes with `NgClass`
|
||||
|
||||
Add or remove multiple CSS classes simultaneously with `ngClass`.
|
||||
|
||||
HELPFUL: To add or remove a _single_ class, use [class binding](/guide/templates/binding#css-class-and-style-property-bindings) rather than `NgClass`.
|
||||
|
||||
### Import `NgClass` in the component
|
||||
|
||||
To use `NgClass`, add it to the component's `imports` list.
|
||||
The following `appHighlight` directive sets the host element's background color when the pointer enters and clears it when the pointer leaves:
|
||||
|
||||
```angular-ts
|
||||
import {NgClass} from '@angular/common';
|
||||
import {Directive, ElementRef, inject} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
/* ... */
|
||||
imports: [NgClass],
|
||||
@Directive({
|
||||
selector: '[appHighlight]',
|
||||
host: {
|
||||
'(mouseenter)': 'onMouseEnter()',
|
||||
'(mouseleave)': 'onMouseLeave()',
|
||||
},
|
||||
})
|
||||
export class AppComponent {}
|
||||
export class HighlightDirective {
|
||||
private el = inject(ElementRef);
|
||||
|
||||
onMouseEnter() {
|
||||
this.el.nativeElement.style.backgroundColor = 'yellow';
|
||||
}
|
||||
|
||||
onMouseLeave() {
|
||||
this.el.nativeElement.style.backgroundColor = '';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Using `NgClass` with an expression
|
||||
Apply the directive by adding its selector as an attribute on an element:
|
||||
|
||||
On the element you'd like to style, add `[ngClass]` and set it equal to an expression.
|
||||
In this case, `isSpecial` is a boolean set to `true` in `app.component.ts`.
|
||||
Because `isSpecial` is true, `ngClass` applies the class of `special` to the `<div>`.
|
||||
|
||||
<docs-code header="app.component.html" path="adev/src/content/examples/built-in-directives/src/app/app.component.html" region="special-div"/>
|
||||
|
||||
### Using `NgClass` with a method
|
||||
|
||||
1. To use `NgClass` with a method, add the method to the component class.
|
||||
In the following example, `setCurrentClasses()` sets the property `currentClasses` with an object that adds or removes three classes based on the `true` or `false` state of three other component properties.
|
||||
|
||||
Each key of the object is a CSS class name.
|
||||
If a key is `true`, `ngClass` adds the class.
|
||||
If a key is `false`, `ngClass` removes the class.
|
||||
|
||||
<docs-code header="app.component.ts" path="adev/src/content/examples/built-in-directives/src/app/app.component.ts" region="setClasses"/>
|
||||
|
||||
1. In the template, add the `ngClass` property binding to `currentClasses` to set the element's classes:
|
||||
|
||||
<docs-code header="app.component.html" path="adev/src/content/examples/built-in-directives/src/app/app.component.html" region="NgClass-1"/>
|
||||
|
||||
For this use case, Angular applies the classes on initialization and in case of changes caused by reassigning the `currentClasses` object.
|
||||
The full example calls `setCurrentClasses()` initially with `ngOnInit()` when the user clicks on the `Refresh currentClasses` button.
|
||||
These steps are not necessary to implement `ngClass`.
|
||||
|
||||
## Setting inline styles with `NgStyle`
|
||||
|
||||
HELPFUL: To add or remove a _single_ style, use [style bindings](guide/templates/binding#css-class-and-style-property-bindings) rather than `NgStyle`.
|
||||
|
||||
### Import `NgStyle` in the component
|
||||
|
||||
To use `NgStyle`, add it to the component's `imports` list.
|
||||
|
||||
```angular-ts
|
||||
import {NgStyle} from '@angular/common';
|
||||
|
||||
@Component({
|
||||
/* ... */
|
||||
imports: [NgStyle],
|
||||
})
|
||||
export class AppComponent {}
|
||||
```angular-html
|
||||
<p appHighlight>Highlight me!</p>
|
||||
```
|
||||
|
||||
Use `NgStyle` to set multiple inline styles simultaneously, based on the state of the component.
|
||||
Every element that carries the `appHighlight` attribute gains the same hover behavior, with the logic defined in one place.
|
||||
|
||||
1. To use `NgStyle`, add a method to the component class.
|
||||
## Types of directives
|
||||
|
||||
In the following example, `setCurrentStyles()` sets the property `currentStyles` with an object that defines three styles, based on the state of three other component properties.
|
||||
Angular has two primary types of directives:
|
||||
|
||||
<docs-code header="app.component.ts" path="adev/src/content/examples/built-in-directives/src/app/app.component.ts" region="setStyles"/>
|
||||
|
||||
1. To set the element's styles, add an `ngStyle` property binding to `currentStyles`.
|
||||
|
||||
<docs-code header="app.component.html" path="adev/src/content/examples/built-in-directives/src/app/app.component.html" region="NgStyle-2"/>
|
||||
|
||||
For this use case, Angular applies the styles upon initialization and in case of changes.
|
||||
To do this, the full example calls `setCurrentStyles()` initially with `ngOnInit()` and when the dependent properties change through a button click.
|
||||
However, these steps are not necessary to implement `ngStyle` on its own.
|
||||
| Directive type | Details |
|
||||
| :-------------------------------------------------------------- | :-------------------------------------------------------------------------------- |
|
||||
| [Attribute directives](guide/directives/attribute-directives) | Change the appearance or behavior of an element, component, or another directive. |
|
||||
| [Structural directives](guide/directives/structural-directives) | Change the DOM layout by adding and removing DOM elements. |
|
||||
|
||||
## What's next
|
||||
|
||||
Learn more about each type of directive in the following guides.
|
||||
|
||||
<docs-pill-row>
|
||||
<docs-pill href="guide/directives/attribute-directives" title="Attribute Directives"/>
|
||||
<docs-pill href="guide/directives/structural-directives" title="Structural Directives"/>
|
||||
<docs-pill href="guide/directives/attribute-directives" title="Attribute directives"/>
|
||||
<docs-pill href="guide/directives/structural-directives" title="Structural directives"/>
|
||||
<docs-pill href="guide/directives/directive-composition-api" title="Directive composition API"/>
|
||||
</docs-pill-row>
|
||||
|
||||
Reference in New Issue
Block a user