23

我知道 Angular2 没有双向数据绑定,但有没有办法模仿 Angular1.x 的双向数据绑定行为?

4

8 回答 8

20

注意 - 向下滚动 ng-model 绑定的答案

您实际上可以这样做,只是您需要调用内部 changelistener tick(类似于摘要)来更新区域中的绑定,您可以为此添加一个(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;
}

演示



更新 - 用于 2 向绑定的 ng-model

虽然 Angular2 默认是一次性绑定的,但是ngModel引入了糖来实现双向绑定。例如,您可以这样做:

<input ngControl="name" [(ngModel)]="name">

这里使用方括号 ( [..]) 表示属性绑定和圆括号 ( (..)) 用于事件绑定。基本上,当您使用 时ng-model,您启用这两个绑定ngModel更像是一个事件。在幕后,它创建了一个可观察事件(with EventEmitter)来跟踪value绑定元素的变化并分别更新绑定属性。例如:-

包括 formDirectives:

 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]
})

演示

还可以通过创建 ng-model 事件及其工作原理阅读Victor Savkin关于 angular2 中的双向绑定的精彩文章。

于 2015-05-27T02:06:11.893 回答
15

您现在可以使用 ngModel 使用以下语法简单地执行此操作:

<input [(ngModel)]="myProp" />

方括号和圆括号的组合表示“双向绑定”。

请在此处查看 plunk

于 2016-05-25T15:40:07.583 回答
11

是的,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>

您还可以在实际更改的位置发出新值。但是我发现在 setter 方法中全局执行此操作非常方便,并且不必费心,例如当我将它直接绑定到我的视图时。

于 2016-10-09T11:48:52.997 回答
6

You can do this by attaching to the events on the input field and updating the internal value as is done in this example:

http://plnkr.co/edit/lOFzuWtUMq1hCnrm9tGA?p=preview

Create a component that has an internal attribute that holds the label this.label and a callback changeLabel that expects an event object

@Component({
  selector: 'app',
  templateUrl: 'bound.html'
})
class App {
  label: string;
  constructor() {
    this.label = 'default label'
  }
  changeLabel(event) {
    this.label = event.target.value;
  }
}

bootstrap(App);

The create your template and attach the callback to the appropriate event (you could attach it to the keypress event but then you might need a timeout. I attached it to the change event for simplicity (which means you might need to tab off the input to see the update).

<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)"/>
于 2015-05-26T21:24:04.253 回答
5

还有另一种方法可以欺骗 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>

电影对象本身是单向绑定的,但它的所有属性都可以用于双向绑定。

于 2016-06-13T01:35:47.047 回答
2

这是一个简单的 plunker,它根据Angular2 2.0.0-beta.17演示了一种方式、两种方式和事件驱动的方法

http://plnkr.co/eXZMoU

双向事件和属性

<input [(ngModel)]="name" />

单向属性

<input [value]="name" />

事件驱动

<input (input)="name=$event.target.value">

我们可以挖掘 Angular 文档以获取更多信息

[2020 年 1 月 26 日更新]

由于 Angular2 beta 库已从项目 CDN 中删除!上面的 plnkr 链接不再起作用。

使用下面新的 plnkr Angular 6+ 页面,我将上一页移植到 NPMJS、新的 Angular 版本和新的 plnkr!

http://next.plnkr.co/edit/4okdOSgw3SMvdktR?preview

于 2016-11-09T14:59:09.823 回答
1

从文档:

双向绑定 ( [(...)])

您通常希望在用户进行更改时既显示数据属性又更新该属性。

在元素方面,它结合了设置特定元素属性和侦听元素更改事件。

Angular 为此提供了一种特殊的双向数据绑定语法,[(x)]. 该[(x)]语法将属性绑定[x]的括号 , 与事件绑定的括号 ,组合在一起(x)

[( )] = BANANA IN A BOX

想象一个盒子里的香蕉,以记住括号放在括号内。

有关详细信息,请参阅

于 2019-03-05T19:25:52.120 回答
0

很简单,试试这个;

<input [(ngModel)]="property" placeholder="property Value"/>
<h1>{{property}}</h1>
于 2016-06-17T18:10:12.673 回答