gpt4 book ai didi

typescript - Angular 2 : how to properly implement 2-way databinding without incurring in endless loop

转载 作者:搜寻专家 更新时间:2023-10-30 21:31:04 27 4
gpt4 key购买 nike

仍在继续我的 Angular2(测试版 1)新手之旅,我试图了解如何正确实现双向绑定(bind),而不会让我的应用程序陷入无限循环。

请在这个 Plunker 找到示例重现:http://plnkr.co/edit/83NeiUCEpPvYvUXIkl0g .只需运行并单击按钮即可。

我的场景:

  • 一个指令包装了 Ace 代码编辑器并公开了一个 text 属性和一个 textChanged 事件。
  • 一个 (XML) 编辑器组件使用这个指令。它应该能够响应底层编辑器中的更改以更新其 XML 代码,并根据其 XML 代码在底层编辑器中设置新文本。

我的问题是,每当编辑器组件以编程方式设置其 xml 属性时,这会触发底层 Ace 编辑器中的更改,进而触发 text-changed 事件,该事件又由编辑器组件的回调,等等。这会产生无限循环,您可以看到编辑器的文本闪烁。我在这里做错了什么?

指令代码如下:

import {Component,Directive,EventEmitter,ElementRef} from 'angular2/core';
declare var ace: any;

@Directive({
selector: "ace-editor",
inputs: [
"text"
],
outputs: [
"textChanged"
]
})
export class AceDirective {
private editor : any;
public textChanged: EventEmitter<string>;

set text(s: string) {
if (s === undefined) return;
let sOld = this.editor.getValue();
if (sOld === s) return;
this.editor.setValue(s);
this.editor.clearSelection();
this.editor.focus();
}

get text() {
return this.editor.getValue();
}

constructor(elementRef: ElementRef) {
var dir = this;
this.textChanged = new EventEmitter<string>();

let el = elementRef.nativeElement;
this.editor = ace.edit(el);
let session = this.editor.getSession();
session.setMode("ace/mode/xml");
session.setUseWrapMode(true);

this.editor.on("change", (e) => {
let s = dir.editor.getValue();
dir.textChanged.next(s);
});
}
}

这是编辑器组件:

import {Component,EventEmitter} from "angular2/core";
import {AceDirective} from "./ace.directive";

@Component({
selector: "my-editor",
directives: [AceDirective],
template: `<div style="border:1px solid red">
<ace-editor id="editor" [text]="xml" (textChanged)="onXmlChanged($event)"></ace-editor>
</div>
<div><button (click)="changeXml()">set xml</button></div>`,
inputs: [
"xml"
]
})
export class EditorComponent {
private _xml: string;

// using a property here so that I can set a breakpoint
public set xml(s: string) {
this._xml = s;
}
public get xml() : string {
return this._xml;
}

constructor() {
this._xml = "";
}

public onXmlChanged(xml: string) {
this._xml = xml;
}

// an action which somehow changes the XML content
public changeXml() {
this._xml = "<x>abc</x>";
}
}

最佳答案

只需执行 [(ngModel)]="property"语法。尽管它看起来像旧的双向绑定(bind)实际上正在将其分解为两种不同的单向绑定(bind),一种用于输入,一种用于输出,但 Angular 2 处理更改的方式和他在引擎盖下的脏检查循环是什么改变了,不会让你做一个无限循环。

关于typescript - Angular 2 : how to properly implement 2-way databinding without incurring in endless loop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34793538/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com