AngularJS:textarea绑定到JSON对象显示“object-object”

我对AngularJS相当新颖。

我正试图将一个对象绑定到一个textarea。

HTML:

<textarea rows="5" cols="10" ng-model="menuItem.preset"></textarea> 

模型:

 { "kind": "title", "label": "ADD_TITLE", "iconSrc": "textTitle.png", "experimentInclude": "", "experimentExclude": "three", "preset": { "compType": "richTitle", "styleId": "txtNew" } } 

结果:

json显示为对象

如何显示JSONstring化(并将其另存为对象)?

您需要一个自定义指令来分析对象的input,并将对象分别显示为一个string:

就像是:

 angular.module('yourApp').directive('jsonText', function() { return { restrict: 'A', require: 'ngModel', link: function(scope, element, attr, ngModel) { function into(input) { return JSON.parse(input); } function out(data) { return JSON.stringify(data); } ngModel.$parsers.push(into); ngModel.$formatters.push(out); } }; }); 
 <textarea json-text rows="5" cols="10" ng-model="menuItem.preset"></textarea> 

小提琴: http : //jsfiddle.net/HzYQn/

我刚刚研究了什么,我相信是做到这一点的最“正确”的方式,因为我需要它为我的https://github.com/vorburger/MUI.js …所以这里是一个Plonker与我的解决scheme。 它基于&本质上是一个特殊的情况(即应用)相关的问题如何在angular.js中进行双向过滤? 添加的扭曲是模型更新也应该改变文本框..这就是$ watch / $ setViewValue / $渲染的东西。

 var app = angular.module('app', []); app.directive('jsonText', function() { return { restrict: 'A', // only activate on element attribute require: 'ngModel', // get a hold of NgModelController link: function(scope, element, attrs, ngModelCtrl) { var lastValid; // push() if faster than unshift(), and avail. in IE8 and earlier (unshift isn't) ngModelCtrl.$parsers.push(fromUser); ngModelCtrl.$formatters.push(toUser); // clear any invalid changes on blur element.bind('blur', function() { element.val(toUser(scope.$eval(attrs.ngModel))); }); // $watch(attrs.ngModel) wouldn't work if this directive created a new scope; // see https://stackoverflow.com/questions/14693052/watch-ngmodel-from-inside-directive-using-isolate-scope how to do it then scope.$watch(attrs.ngModel, function(newValue, oldValue) { lastValid = lastValid || newValue; if (newValue != oldValue) { ngModelCtrl.$setViewValue(toUser(newValue)); // TODO avoid this causing the focus of the input to be lost.. ngModelCtrl.$render(); } }, true); // MUST use objectEquality (true) here, for some reason.. function fromUser(text) { // Beware: trim() is not available in old browsers if (!text || text.trim() === '') { return {}; } else { try { lastValid = angular.fromJson(text); ngModelCtrl.$setValidity('invalidJson', true); } catch (e) { ngModelCtrl.$setValidity('invalidJson', false); } return lastValid; } } function toUser(object) { // better than JSON.stringify(), because it formats + filters $$hashKey etc. return angular.toJson(object, true); } } }; }); app.controller('Ctrl', ['$scope', function($scope) { $scope.model = {}; $scope.model.data = { "kind": "title", "label": "ADD_TITLE", "iconSrc": "textTitle.png", "experimentInclude": "", "experimentExclude": "three", "preset": { "compType": "richTitle", "styleId": "txtNew" } }; } ]); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <div ng-app="app" class="container"> <div ng-controller="Ctrl" class="row"> <textarea json-text ng-model='model.data' rows="15"></textarea> <p>{{ model.data }}</p> </div> </div> 

尝试使用jsonfilter

 <textarea rows="5" cols="10" > {{ menuItem.preset | json }} </textarea> 

这是我们的JSON指令有效性检查:

 app.directive('jsonInput', function () { 'use strict'; return { restrict: 'A', require: 'ngModel', link: function (scope, elem, attr, ctrl) { ctrl.$parsers.unshift(function(input) { try { var obj = JSON.parse(input); ctrl.$setValidity('jsonInput', true); return obj; } catch (e) { ctrl.$setValidity('jsonInput', false); return null; } }); ctrl.$formatters.unshift(function(data) { if (data == null) { ctrl.$setValidity('jsonInput', false); return ""; } try { var str = JSON.stringify(data); ctrl.$setValidity('jsonInput', true); return str; } catch (e) { ctrl.$setValidity('codeme', false); return ""; } }); } }; }); 

当用户input无效的JSON时,模型为空。 当模型包含循环引用或为null时,用户将看到一个空string(“”),input无效。

请享用。

你也可以在你的模型上定义toString方法:

  $scope.menuItem.preset.toString = function(){ return JSON.stringify(this); } 

http://jsfiddle.net/ceJ4w/19/

然后同步回来使用手表

http://jsfiddle.net/ceJ4w/20/

但看起来更像是肮脏的黑客而不是解决scheme

你可以通过两步来做到这一点:

是否使用ng-change事件太乱了?

 <textarea ng-model="textmainboardJSON" ng-change="updateMainboard()" 

http://jsfiddle.net/gsw9Q/3/

尝试这个。 它在我的情况下工作

<textarea rows="5" cols="10" >{{menuItem.preset}}</textarea>