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

时间:2014-04-17 18:20:13

标签: json angularjs

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

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

1 个答案:

答案 0 :(得分:1)

更新:http://codepen.io/maxbates/pen/AfEHz

提供的Angular 1.3修订版

我做了一个指令来做到这一点。 如果您有建议我会编辑

Fiddle + Gist

据我所知,除了添加一个错误的函数之外,没有办法取消$ 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);

            }
        };
    });