Я знаю, что Angular2 не имеет двусторонней привязки данных, но есть ли способ имитировать поведение двусторонней привязки данных из Angular1.x?
Двусторонняя привязка данных Angular2
Ответы (8)
Примечание. Прокрутите вниз ответ для привязки ng-модели
На самом деле вы можете это сделать, просто вам нужно вызвать внутренний тик прослушивателя изменений (аналогичный дайджесту), чтобы обновить привязку в зоне. Вы можете просто добавить для этого событие (keyup)
. Точно так же вы можете использовать привязки директив с properties
словарем настроек компонента.
Пример:-
<input #label (keyup)>
<!-- variable #label represented as the element itself and accessible as property on controller instance
You can even bind keyup to a function or another another function and pass value from the label property-->
Отображать как:
<p>{{label.value}}</P>
Родительский компонент имеет текстовое поле и метку.
import { Component, bootstrap} from '@angular/core';
import {Display} from 'display';
@Component({
selector: 'my-app',
template: `<p><b>Parent Component:</b><p><input #label (keyup) (change)="handleChange(label.value)">
<p>{{label.value}}</P> <display [text]="label"></display></p></p>`,
directives: [Display]
})
class MainComponent {
label: any;
constructor() {
}
handleChange(label){
this.label = label;
console.log(this.label);
}
}
Теперь отображаем его и в дочернем компоненте:
@Component({
selector: 'edit',
template: `<p><b>Child Component:</b></p>{{text.value}}`
})
export class Edit {
@Input() text:any;
}
Обновление — ng-модель для двусторонней привязки
Хотя Angular2 по умолчанию имеет однократную привязку, для достижения двусторонней привязки был введен сахар ngModel
. С этим вы могли бы сделать, например:
<input ngControl="name" [(ngModel)]="name">
Здесь использование квадратных скобок ([..]
) предполагает привязку свойства и круглых скобок ((..)
) для привязки события. По сути, когда вы используете ng-model
, вы включаете обе привязки ngModel
, это скорее событие. За кулисами он создает наблюдаемое событие (с EventEmitter
) для отслеживания value
изменений в связанном элементе и обновления связанного свойства соответственно. Например:-
Включить директивы формы:
import {FORM_DIRECTIVES} from '@angular/common';
и с формой
<form (ngSubmit)="onSubmit()" let-f="form">
<input ngControl="name" [(ngModel)]="name">
<button>Click me and check console</button>
</form>
без формы
<input [(ngModel)]="name">
<button (click)="onSubmit()">Click me and check console</button>
больше не нужно включать зависимость formDirectives в аннотацию представления.
@Component({
template: .....,
directives: [FORM_DIRECTIVES]
})
забастовка>
Также прочитайте отличную запись от Виктора Савкина о двусторонней привязке в angular2, создав ng событие модели и как оно работает.
FormsModule
.
- person zed; 02.04.2018
Теперь вы можете просто сделать это с помощью ngModel, используя следующий синтаксис:
<input [(ngModel)]="myProp" />
Сочетание квадратных и круглых скобок означает «двустороннюю привязку».
См. планк здесь
Да, в angular2 есть двусторонняя привязка. См. здесь: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#ngModel
Итак, как использовать его в пользовательских компонентах?
Что мне нравится делать, так это:
private currentSelectedItem: MachineItem;
@Output() selectedItemChange: EventEmitter<MachineItem> = new EventEmitter<MachineItem>();
@Input() set selectedItem(machineItem: MachineItem) {
this.currentSelectedItem = machineItem;
this.selectedItemChange.emit(machineItem);
}
get selectedItem(): MachineItem {
return this.currentSelectedItem;
}
И используйте его как
<admin-item-list [(selectedItem)]="selectedItem"></admin-item-list>
Вы также можете передать новое значение там, где оно фактически изменено. Но мне очень удобно делать это глобально в методе установки, и мне не нужно беспокоиться, например. когда я привязываю его непосредственно к моему представлению.
Вы можете сделать это, присоединившись к событиям в поле ввода и обновив внутреннее значение, как это сделано в этом примере:
http://plnkr.co/edit/lOFzuWtUMq1hCnrm9tGA?p=preview
Создайте компонент с внутренним атрибутом, содержащим метку this.label
, и обратный вызов changeLabel
, который ожидает объект события.
@Component({
selector: 'app',
templateUrl: 'bound.html'
})
class App {
label: string;
constructor() {
this.label = 'default label'
}
changeLabel(event) {
this.label = event.target.value;
}
}
bootstrap(App);
Создайте свой шаблон и прикрепите обратный вызов к соответствующему событию (вы можете прикрепить его к событию keypress
, но тогда вам может понадобиться тайм-аут. Я прикрепил его к событию change
для простоты (это означает, что вам может потребоваться отложить ввод для смотрите обновление).
<label for="myinput">{{label}}</label>
<input id="myinput" type="text"/>
<p></p>You can change the label above by typing something below</p>
<label for="labeltext">New Label Text</label>
<input type="text" id="labeltext" (change)="changeLabel($event)"/>
Есть еще один способ заставить Angular2 использовать двустороннюю привязку. Не передавайте свойство, а объект в компонент. Если вы передаете объект через одностороннюю привязку, все его свойства на самом деле являются двусторонними. Это делает компонент менее универсальным, поскольку ему необходимо знать объект, но во многих случаях он все еще полезен.
У меня есть компонент, который выглядит так:
import { Component, Input } from "@angular/core";
import { NgSwitch, NgSwitchWhen, NgSwitchDefault } from "@angular/common";
export class Movie
{
public Title: string;
public Rating: number;
public Seen: boolean;
}
@Component
({
selector: "hh-image-checkbox",
template: `
<div [ngSwitch]="movie.Seen">
<div *ngSwitchWhen="true">
<img src="/Content/res/CheckTrue.png" (click)="onClick()">
</div>
<div *ngSwitchDefault>
<img src="/Content/res/CheckFalse.png" (click)="onClick()">
</div>
</div>
`,
directives: [NgSwitch, NgSwitchWhen, NgSwitchDefault]
})
export class ImageCheckboxComponent
{
@Input() movie: Movie;
public onClick()
{
this.movie.Seen = !this.movie.Seen;
}
}
Вызывается так:
<hh-image-checkbox [movie]="movie"></hh-image-checkbox>
Сам объект фильма имеет одностороннюю привязку, но все его свойства можно использовать для двусторонней привязки.
NgSwitch, NgSwitchWhen, NgSwitchDefault and add them to
directives. They are provided globally by
PLATFORM_DIRECTIVES`
- person Günter Zöchbauer; 13.06.2016
Вот простой планкер, который демонстрирует односторонний, двусторонний и событийный подходы в действии в соответствии с Angular2 2.0.0-beta.17.
Двустороннее событие и собственность
<input [(ngModel)]="name" />
Односторонняя собственность
<input [value]="name" />
События
<input (input)="name=$event.target.value">
Мы можем найти больше
[ОБНОВЛЕНИЕ 26.01.2020]
Поскольку бета-библиотеки Angular2 удалены из CDN проекта! ссылка выше plnkr больше не работает.
Используйте ниже новую страницу plnkr Angular 6+, я перенес предыдущую страницу в NPMJS, новую версию angular и новый plnkr!
http://next.plnkr.co/edit/4okdOSgw3SMvdktR?preview
Из документов:
Двусторонняя привязка (
[(...)]
)Часто требуется одновременно отображать свойство данных и обновлять это свойство, когда пользователь вносит изменения.
На стороне элемента требуется комбинация установки определенного свойства элемента и прослушивания события изменения элемента.
Angular предлагает для этой цели специальный синтаксис двусторонней привязки данных,
[(x)]
. Синтаксис[(x)]
объединяет скобки привязки свойства[x]
со скобками привязки события(x)
.[( )] = BANANA IN A BOX
Визуализируйте банан в коробке, чтобы помнить, что круглые скобки находятся внутри скобок.
Для получения дополнительной информации см.
- Руководство разработчика Angular — Синтаксис шаблона — Двусторонняя привязка
- Справочник по API Angular
@angular/forms
— директиваngModel
Это просто, попробуйте это;
<input [(ngModel)]="property" placeholder="property Value"/>
<h1>{{property}}</h1>