简体   繁体   中英

ngModel for textarea not working in angular 2

I am trying to print json object in textarea using ngModel .

I have done following:

<textarea style="background-color:black;color:white;" [(ngModel)]='rapidPage' rows="30" cols="120">                             
</textarea>

I want to load the json object in textarea. The above code is loading the rapidPage object in textarea but its showing textarea value as [object Object] .

object:

 this.rapidPage = {            
        "pageRows": [
            {
                "sections": [
                    {
                        "sectionRows": [
                            {
                                "secRowColumns": [                                       
                                ]
                            },
                            {
                                "secRowColumns": [
                                    {
                                        "colName": "users"
                                    }
                                ]
                            },
                            {
                                "secRowColumns": [
                                    {
                                        "colName": "sample"
                                    }
                                ]
                            }
                        ],
                        "width": 0
                    }
                ]
            }
        ],
        "pageName": "DefaultPage",
        "pageLayout": "DEFAULT_LAYOUT",
        "editMode": true
    };

I want to load the data as string. any inputs?

Assuming that you want to bind rapidPage as it is and will only write valid JSON in the textArea.

  • You need to PARSE it when changing the value, and STRINGIFY when showing in textarea.

StackBlitz DEMO

Do the following in your Component code

  rapidPage = {"pageRows":[{"sections":[{"sectionRows":[{"secRowColumns":[]},{"secRowColumns":[{"colName":"users"}]},{"secRowColumns":[{"colName":"sample"}]}],"width":0}]}],"pageName":"DefaultPage","pageLayout":"DEFAULT_LAYOUT","editMode":true}; 
  // your object

  get rapidPageValue () {
    return JSON.stringify(this.rapidPage, null, 2);
  }

  set rapidPageValue (v) {
    try{
    this.rapidPage = JSON.parse(v);}
    catch(e) {
      console.log('error occored while you were typing the JSON');
    };
  }

Template Usage:

<textarea [(ngModel)]='rapidPageValue' rows="30" cols="120">                             
</textarea>
<textarea class="form-control" 
          name="message"
          rows="8"
          [(ngModel)]="Obj.message"
          #message='ngModel'
          ></textarea>

for Two way binding You just need to add attribute in textarea tag name="message" , ONLY [(ngModel)] works 100%!.

For binding textarea values in Angular 2 you can use the change-function:

Template

<textarea id="some-value" (change)="doTextareaValueChange($event)">{{textareaValue}}</textarea>

Component

export class AppComponent implements OnInit {
  private textareaValue = '';
  doTextareaValueChange(ev) {
    try {
      this.textareaValue = ev.target.value;
    } catch(e) {
      console.info('could not set textarea-value');
    }
  }
}

Unless you really want to have sync in between, you would normally implement a button to save/apply the change when it's finished json editing. If that is the case, your render is easy.

<textarea #textbox>{{ rapidPage | json }}</textarea>

Make sure no other space or return character in between the above line.

Then an traditional button, ex.

<a (click)="updateRapidPage(textbox.value)">Apply</a>

I found this is better in some case than brutal [(rapidPage)] .

You can also use @ViewChild('textbox') input inside the component to access this variable.

ngModel works if

  1. There is a form wrapped around it & textarea has a name attribute added to it.

If you not you can use the following syntax to achieve the same effect

<textarea [value]="strVariableInComponent" (input)="strVariableInComponent = $event.target.value;"></textarea>

Can you test with this:

<textarea #textbox (change)="text = textbox.value" style="width:100%;">{{ text }}</textarea>

Regards

As per documentation [()] is for two way syntax sugar to remove the boilerplate. What event is being invoked at this? Irrespective, you can put a string output also alongwith the event in below code

Probably try the below code implemetation for your string output

@Directive({
  selector: '[ngModel]',
  host: {
    "[value]": 'ngModel',
    "(input)": "ngModelChange.next($event.target.value)"
  }
})
class NgModelDirective {
  @Input() ngModel:any; // stored value
  @Output() ngModelChange:EventEmitter; = new EventEmitter() // an event emitter
}

You can stringify your json and use in the ngModel like this -

<textarea style="height:100px; width:300px;background-color:black;color:white;" [(ngModel)]='rapidPage' rows="30" cols="120">
    </textarea>

ArrayDemo: Array<any> = [{"name":"pardeep","last":"jain"}]
  rapidPage = JSON.stringify(this.ArrayDemo);

Working Example Working Example

Browser shows [object object] because angular unables to parse the JSON the asign the value in ngModel you must need a string so convert this using JSON.stringify

I find that importing FormsModule from @angular/forms solves the issue.

In app.module.ts

import { FormsModule } from '@angular/forms';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    ...
    FormsModule
  ],
...
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM