2016-05-02 19 views
0

私は素晴らしいwysiwygコンポーネントを構築することによってangular2を学ぼうとしていますが、今はレンガの壁に当たっています。だから、ここに私のコードは次のとおりです。Angular2 wysiwyg component投稿していません

app.component.ts(私は角のチュートリアルから英雄-フォームを修正)私はコンポーネントをテストするために使用しているフォームです:

import {Component} from 'angular2/core'; 
import {NgForm} from 'angular2/common'; 
import { Article } from './article'; 
import {aWysiwygComponent} from './aWysiwyg.component' 

@Component({ 
    selector: 'test-form', 
    templateUrl: 'app/article-form.component.html', 
    directives: [aWysiwygComponent] 
}) 
export class ArticleFormComponent { 
    model = new Article(18, 'Dr IQ', 'Chuck Overstreet'); 
    submitted = false; 
    onSubmit() { this.submitted = true; } 
    // Reset the form with a new hero AND restore 'pristine' class state 
    // by toggling 'active' flag which causes the form 
    // to be removed/re-added in a tick via NgIf 
    // TODO: Workaround until NgForm has a reset method (#6822) 
    active = true; 
    newArticle() { 
    this.model = new Article(42, '', ''); 
    this.active = false; 
    setTimeout(()=> this.active=true, 0); 
    } 
} 

と、このためのHTML次のとおりです。

<div class="container"> 
    <div [hidden]="submitted"> 
    <h1>Hero Form</h1> 
    <form *ngIf="active" (ngSubmit)="onSubmit()" #articleForm="ngForm"> 
     <div class="form-group"> 
     <label for="name">Name</label> 
     <input type="text" class="form-control" required 
      [(ngModel)]="model.name" 
      ngControl="name" #name="ngForm" > 
     <div [hidden]="name.valid || name.pristine" class="alert alert-danger"> 
      Name is required 
     </div> 
     </div> 
     <div class="form-group"> 
      <label for="content">Content</label> 
      <aWysiwyg [(model)]="model.content"></aWysiwyg> 
     </div> 
     <button type="submit" class="btn btn-default" [disabled]="!articleForm.form.valid">Submit</button> 
     <button type="button" class="btn btn-default" (click)="newArticle()">New Article</button> 
    </form> 
    </div> 
    <div [hidden]="!submitted"> 
    <h2>You submitted the following:</h2> 
    <div class="row"> 
     <div class="col-xs-3">Name</div> 
     <div class="col-xs-9 pull-left">{{ model.name }}</div> 
    </div> 
    <div class="row"> 
     <div class="col-xs-3">Content</div> 
     <div class="col-xs-9 pull-left">{{ model.content }}</div> 
    </div> 
    <br> 
    <button class="btn btn-default" (click)="submitted=false">Edit</button> 
    </div> 
</div> 

、ここでは、WYSIWYGのコンポーネントは次のとおりです。

import {Component, ViewEncapsulation, Input} from 'angular2/core'; 
import {ToolbarComponent} from './components/toolbar.component'; 
import {EditableComponent} from './components/editable.component'; 
import { NgForm, FORM_PROVIDERS, FORM_DIRECTIVES } from 'angular2/common'; 


@Component({ 
    selector: 'aWysiwyg', 
    templateUrl: '../app/templates/editor.html', 
    styleUrls:['./app/styles/bootstrap.min.css', './app/styles/styles.css', './app/styles/font-awesome.min.css'], 
    encapsulation: ViewEncapsulation.None, 
    providers: [FORM_PROVIDERS], 
    directives: [ToolbarComponent, EditableComponent, FORM_DIRECTIVES] 
}) 
export class aWysiwygComponent { 
    @Input() model:any; 
} 

HTML:

<section class="editor col-sm-24 col-lg-24"> 
    <aToolbar class="row">Loading...</aToolbar> 
    <aEditable [(model)]="model" class="row">Loading...</aEditable> 
</section> 
<textarea class="form-control" id="hiddenInput" hidden>{{model}}</textarea> 

編集可能なエリアコンポーネント:

import {Component, Input, AfterViewInit} from 'angular2/core'; 
import { NgForm, FORM_PROVIDERS, FORM_DIRECTIVES } from 'angular2/common'; 

@Component({ 
    selector: 'aEditable', 
    templateUrl: './app/templates/editable.html', 
    providers: [FORM_PROVIDERS], 
    directives: [FORM_DIRECTIVES] 
}) 
export class EditableComponent implements AfterViewInit { 
    @Input() model:any; 

    ngAfterViewInit(){ 
     jQuery('#editable-area').keyup(function(){ 
      jQuery('#hiddenInput').text(jQuery('#editable-area').html()) 
     }) 
    } 
} 

とhtml:

<section id="editable"> 
    <div id="editable-area" contenteditable > 
     {{model}} 
    </div> 
</section> 

プロジェクトの残りの部分は、ツールバーのための部品のちょうど束です。問題は、私がフォームを提出するときに私はwysiwygから何も得ていない、私はそれにコンテンツを書いていると私はそのコンテンツがtextareaにコピーされているのを見て、それはフォームの残りの部分と一緒に投稿しないことです。私はコンソールをチェックし、例外はありません、すべてうまく見えます。誰かが私が間違っているのを見ることができますか?ありがとうございました。

+1

あなたが必要カスタム要素が動作するための 'ControlValueAccessor' i 'ngModel' http://stackoverflow.com/search?q=%5Bangular2%5D+controlvalueaccessor –

答えて

1

ここには2つのものがあります。

あなたは2つの結合方法を活用したい場合は、あなたもあなたのコンポーネントでOutputを持っている必要があります:

@Component({ 
    selector: 'aEditable', 
    templateUrl: './app/templates/editable.html', 
    providers: [FORM_PROVIDERS], 
    directives: [FORM_DIRECTIVES] 
}) 
export class EditableComponent implements AfterViewInit { 
    @Input() model:any; 
    // The name is important here (the suffix "Change") to be 
    // able to use the syntax shortcut: [(model)] 
    @Output() modelChange:EventEmitter<any> = new EventEmitter(); 

    ngAfterViewInit(){ 
    jQuery('#editable-area').keyup(() => { 
     let content = jQuery('#editable-area').html(); 
     this.modelChange.emit(content); 
     jQuery('#hiddenInput').text(content); 
    }); 
    } 
} 

はまた、あなたのaEditableコンポーネントがngModel/ngControl準拠しています。つまり、フォームの検証とグローバルな状態には参加できません。この機能が必要な場合は、カスタム値アクセサを実装する必要があります。

const EDITABLE_VALUE_ACCESSOR = new Provider(NG_VALUE_ACCESSOR, { useExisting: forwardRef(() => EditableComponent), multi: true}); 

@Component({ 
    selector: 'aEditable', 
    templateUrl: './app/templates/editable.html', 
    providers: [FORM_PROVIDERS, EDITABLE_VALUE_ACCESSOR], 
    directives: [FORM_DIRECTIVES] 
}) 
export class EditableComponent implements ControlValueAccessor { 
    content:string; 

    onChange = (_) => {}; 
    onTouched =() => {}; 

    writeValue(value: any): void { 
    this.content = value; 
    // write in the DOM 
    } 

    ngAfterViewInit(){ 
    jQuery('#editable-area').keyup(() => { 
     this.content = jQuery('#editable-area').html(); 
     jQuery('#hiddenInput').text(this.content); 
     this.onChange(content); 
    }); 
    } 

    registerOnChange(fn: (_: any) => void): void { this.onChange = fn; } 
    registerOnTouched(fn:() => void): void { this.onTouched = fn; } 
} 

終了するには、jQueryを使用する代わりにAngular2のサポートを利用してDOMとやりとりすることができます。 @ViewChildデコレータと例えば:

<section #editable> 
    <div id=#editableArea contenteditable > 
    {{model}} 
    </div> 
</section> 

とコンポーネント

@ViewChild('editable') 
editableElement:ElementRef; 

@ViewChild('editableArea') 
editableAreaElement:ElementRef; 

constructor(private renderer:Renderer) { 
} 

onAfterViewInit() { 
    (...) 
} 

で編集可能なコンテンツに関するこの質問にも興味を起こさできます

関連する問題