@Input是否提供双向绑定?

Rin*_*ema 5 input angular

我认为@Input的工作方式将直接表示“不!”。这个问题。但是,今天我偶然发现了一些奇怪的行为,或者也许我一直以为@Input是错误的方式。

我已经进行了一次突袭来显示该问题。这发生在Angular 7.0.1的stackblitz中,但是在我的本地项目中,它也发生在Angular 6.1.2中。

堆栈闪电展示了一个具有对象的简单父组件。该对象通过@Input传递给子组件。子组件和父组件均具有更改对象的功能。它们也都在模板中显示对象的值。

我希望看到当父对象更改对象时,它将在子对象中更改它。但是,我没想到当孩子更改对象时,它也会为父对象更改它。堆栈闪电确实显示了此行为。我一直认为您需要通过@Output显式发出一个事件,以使流程流向父级并在子级组件中进行更改。

Con*_*Fan 10

答案是不”。在您的示例中,您传递给@Input属性的值是对对象的引用。如果您有双向绑定,您可以在子组件中为该属性分配一个新对象:

this.thing = { name: "world", nbm: 10 };
Run Code Online (Sandbox Code Playgroud)

并且父组件中的相应属性将相应更新。事实并非如此,正如您在此 stackblitz 中所见

但是,由于父组件和子组件引用同一个对象,因此它们都可以修改其一个属性,并且会在另一个组件中观察到该更改。


为了实现双向绑定,您可以添加一个@Output同名的属性后跟Change,并在发生更改时发出事件:

@Input() thing: any;
@Output() thingChange = new EventEmitter();

setNewObject(){
  this.thing = { name: "world", nmb: 10 };
  this.thingChange.emit(this.thing);
}
Run Code Online (Sandbox Code Playgroud)

如果使用双向绑定语法,则更改将反映到父组件:

<child2 [(thing)]="thing"></child2>
Run Code Online (Sandbox Code Playgroud)

有关演示,请参阅此 stackblitz


如果要防止子组件修改原始对象,则应绑定对象属性而不是对象本身:

@Input() thingName: string;
@Input() thingNmb: number;
Run Code Online (Sandbox Code Playgroud)
<child [thingName]="thing.name" [thingNmb]="thing.nmb"></child>
Run Code Online (Sandbox Code Playgroud)