如何将JSON作为字符串绑定到textarea,以便我可以直接编辑它?
我只希望我的模型在有效时传播。
答案 0 :(得分:1)
更新:http://codepen.io/maxbates/pen/AfEHz
提供的Angular 1.3修订版我做了一个指令来做到这一点。 如果您有建议我会编辑
据我所知,除了添加一个错误的函数之外,没有办法取消$ parsers管道中的模型更新(并查看ngModelCtrl源似乎验证了这一点)。
请注意,您不要直接在textarea上使用ng-model。此解决方案添加了自己的ngModel,绑定到中间对象,并且只有在JSON有效时才会传播更改。
'use strict';
/*
example usage: <textarea json-edit="myObject" rows="8" class="form-control"></textarea>
jsonEditing is a string which we edit in a textarea. we try parsing to JSON with each change. when it is valid, propagate model changes via ngModelCtrl
use isolate scope to prevent model propagation when invalid - will update manually. cannot replace with template, or will override ngModelCtrl, and not hide behind facade
will override element type to textarea and add own attribute ngModel tied to jsonEditing
As far as I know, there is currently no way to achieve this using $parsers (other than one of the function errors and kills the pipeline)
*/
angular.module('myApp')
.directive('jsonEdit', function () {
return {
restrict: 'A',
require: 'ngModel',
template: '<textarea ng-model="jsonEditing"></textarea>',
replace : true,
scope: {
model: '=jsonEdit'
},
link: function (scope, element, attrs, ngModelCtrl) {
function setEditing (value) {
scope.jsonEditing = angular.copy(JSON2String(value));
}
function updateModel (value) {
scope.model = string2JSON(value);
}
function setValid() {
ngModelCtrl.$setValidity('json', true);
}
function setInvalid () {
ngModelCtrl.$setValidity('json', false);
}
function string2JSON(text) {
try {
return angular.fromJson(text);
} catch (err) {
setInvalid();
return text;
}
}
function JSON2String(object) {
// better than JSON.stringify(), because it formats + filters $$hashKey etc.
// NOTE that this will remove all $-prefixed values
return angular.toJson(object, true);
}
function isValidJson(model) {
var flag = true;
try {
angular.fromJson(model);
} catch (err) {
flag = false;
}
return flag;
}
//init
setEditing(scope.model);
//check for changes going out
scope.$watch('jsonEditing', function (newval, oldval) {
if (newval != oldval) {
if (isValidJson(newval)) {
setValid();
updateModel(newval);
} else {
setInvalid();
}
}
}, true);
//check for changes coming in
scope.$watch('model', function (newval, oldval) {
if (newval != oldval) {
setEditing(newval);
}
}, true);
}
};
});