angular:如何将字符串化json绑定到textarea?

angular:如何将字符串化json绑定到textarea?,json,angularjs,Json,Angularjs,如何将JSON作为字符串绑定到textarea,以便直接编辑它 我只希望我的模型在有效时传播。更新:Angular 1.3的修订版可在 '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 par

如何将JSON作为字符串绑定到textarea,以便直接编辑它


我只希望我的模型在有效时传播。

更新:Angular 1.3的修订版可在

'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);

            }
        };
    });

我做了一个指令来做这件事如果您有建议,我将对其进行编辑

+

据我所知,除了添加一个会导致错误的函数之外,没有办法取消$parsers管道中的模型更新(查看ngModelCtrl源代码似乎可以验证这一点)

请注意,您不直接在textarea上使用ng模型。这个解决方案添加了自己的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);

            }
        };
    });
“严格使用”;
/*
用法示例:
jsonEditing是我们在文本区域中编辑的字符串。我们尝试在每次更改时解析到JSON。有效时,通过ngModelCtrl传播模型更改
当无效时,使用隔离作用域防止模型传播-将手动更新。无法替换为模板,或将重写ngModelCtrl,而不会隐藏在facade后面
将把元素类型覆盖到textarea,并将自己的属性ngModel添加到jsonEditing
据我所知,目前无法使用$parsers实现这一点(除了一个函数错误和终止管道之外)
*/
angular.module('myApp')
.directive('jsonEdit',函数(){
返回{
限制:“A”,
要求:'ngModel',
模板:“”,
替换:正确,
范围:{
模型:'=jsonEdit'
},
链接:函数(范围、元素、属性、ngModelCtrl){
函数集编辑(值){
scope.jsonEditing=angular.copy(JSON2String(value));
}
函数updateModel(值){
scope.model=string2JSON(值);
}
函数setValid(){
ngModelCtrl.$setValidity('json',true);
}
函数集无效(){
ngModelCtrl.$setValidity('json',false);
}
函数string2JSON(文本){
试一试{
返回angular.fromJson(文本);
}捕捉(错误){
setInvalid();
返回文本;
}
}
函数JSON2String(对象){
//优于JSON.stringify(),因为它格式化+过滤器$$hashKey等。
//请注意,这将删除所有以$为前缀的值
返回angular.toJson(object,true);
}
函数isValidJson(模型){
var标志=真;
试一试{
fromJson(模型);
}捕捉(错误){
flag=false;
}
返回标志;
}
//初始化
setEditing(scope.model);
//检查正在进行的更改
作用域:$watch('jsonEditing',函数(newval,oldval){
如果(newval!=oldval){
if(isValidJson(newval)){
setValid();
更新模型(newval);
}否则{
setInvalid();
}
}
},对);
//检查是否有变化
范围:$watch('型号'),功能(新值,旧值){
如果(newval!=oldval){
设置编辑(newval);
}
},对);
}
};
});