首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Angular2 2-父组件和指令之间的双向绑定

Angular2 2-父组件和指令之间的双向绑定
EN

Stack Overflow用户
提问于 2016-01-13 08:12:14
回答 1查看 792关注 0票数 2

参见下面的更新

我仍然在使用Angular2 Beta,我正在尝试实现一个场景,其中一个“编辑器”组件模板包含一个包装Ace编辑器的指令。因此,“编辑器”组件是Ace包装器指令的父级,我希望从该指令中获取代码或将代码设置到其中。

虽然指令本身工作正常,但是当我将它包含在这个组件中时,我没有看到任何显示;但是浏览器的控制台中没有显示错误。您可以在这个柱塞中找到一个reprohttp://plnkr.co/edit/kzclJLIX6hRMWa14A0Pb

在我的实现中,包装Ace编辑器的ace.directive指令具有一个text属性和一个textChanged事件。

代码语言:javascript
复制
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;
    private settingText : boolean;
    public textChanged: EventEmitter<string>;

    set text(s: string) {
        let sOld = this.editor.getValue();
        if (sOld === s) return;

        this.settingText = true;
        this.editor.setValue(s);
        this.editor.clearSelection();
        this.editor.focus();
        this.settingText = false;
    }

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

        let el = elementRef.nativeElement;
        this.editor = ace.edit(el);

        this.editor.on("change", (e) => {
            if (dir.settingText) return;
            dir.textChanged.next(dir.editor.getValue());
        });
    }
}

editor.component组件使用这个指令:它有一个xml属性,表示正在编辑的XML代码。它的模板包含如下指令:

代码语言:javascript
复制
<ace-editor id="editor" [text]="xml" (textChanged)="onXmlChanged()"></ace-editor>

即指令的text属性绑定到父组件的xml属性,指令的textChanged事件由父组件的onXmlChanged函数处理。

作为一个双向数据库,AFAIK I也可以尝试:

代码语言:javascript
复制
<ace-editor id="editor" [(ngModel)]="xml"></ace-editor>

以下是编辑器的代码:

代码语言:javascript
复制
import {Component,EventEmitter} from "angular2/core";
import {AceDirective} from "./ace.directive";

@Component({
    selector: "mit-editor",
    directives: [AceDirective],
    template: `<div>
      <ace-editor id="editor" [text]="xml" (textChanged)="onXmlChanged()"></ace-editor>
    </div>
    `,
    inputs: [
        "xml"
    ]
})
export class EditorComponent { 
    public xml: string;

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

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

更新#1由于某些原因,柱塞不会传输和加载我的.ts文件,而不是先前存在的文件,所以我继续在本地进行故障排除。

至于这个问题,我发现我必须将$event参数添加到模板中的调用中(请参阅我的注释)。我现在的指令是:

代码语言:javascript
复制
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);
        });
    }
}

编辑器组件模板包含如下指令:

代码语言:javascript
复制
<ace-editor id="editor" [text]="xml" (textChanged)="onXmlChanged($event)"></ace-editor>

无论如何,请注意,如果我现在尝试以编程方式设置编辑器的组件xml属性,则角度启动和无穷无尽的循环会触发ace编辑器上的事件,该编辑器再次发出设置xml属性的事件,依此类推。可能只是我做错了什么,但目前我不得不在代码中使用这个黑客,当然我不喜欢它:):

代码语言:javascript
复制
// ...
export class EditorComponent { 
    private _xml: string;
    private _changeFrozenCount: number;

    public set xml(s: string) {
        this._xml = s; 
    }
    public get xml() : string {
        return this._xml;
    }

    constructor(private editorService: EditorService, private xmlService: XmlService) {
        this._xml = "";
    }

    public onXmlChanged(xml: string) {
        if (this._changeFrozenCount > 0) {
            this._changeFrozenCount--;
            return;
        }
        this._xml = xml;
    }

    public changeXml() {
        this._changeFrozenCount = 1;
        this._xml = "<sample>Hello</sample>"
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-13 12:44:51

你忘了加

代码语言:javascript
复制
directives: [EditorComponent]

在app.ts文件中。当前,directives数组在柱塞中为空([])。只需进行此更改即可,如果设置了onXmlChanged($event),则在编辑器内输入时甚至不会出错:)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34761399

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档