Javascript 在文本区域中显示和编辑模型

Javascript 在文本区域中显示和编辑模型,javascript,json,angularjs,object,Javascript,Json,Angularjs,Object,我希望能够在元素中编辑和显示复杂模型。下面是从JSON响应动态生成模型字段的HTML片段: <p>parent uuid*: </p> <input ng-model="parentUuid" capitalize type="text" placeholder="String" class="form-control" style="width:200px; display: inline-block;"/> <br/> <p>

我希望能够在
元素中编辑和显示复杂模型。下面是从JSON响应动态生成模型字段的HTML片段:

<p>parent uuid*: </p>
<input ng-model="parentUuid" capitalize type="text" placeholder="String"
    class="form-control" style="width:200px; display: inline-block;"/> <br/>
<p>resource*:</p>
<select ng-model="childResource" ng-change="loadResourceFields(childResource)" 
    class="form-control" style="width:300px; display: inline-block;">
    <option ng-repeat="childResource in restResources">{{childResource}}</option>
</select>
<div ng-repeat="field in childFields">
    <div ng-show={{!field.isEnum}}>
        <p ng-show={{field.isRequired}}>{{field.name}}*: </p>
        <p ng-show={{!field.isRequired}}>{{field.name}}: </p>
        <input type="text" ng-model="createChildResource[field.name]"
            class="form-control" style="width:200px; display: inline-block;" placeholder="{{parseClassName(field.type)}}">
    </div>
    <div ng-show={{field.isEnum}}>
        <p ng-show={{field.isRequired}}>{{field.name}}*: </p>
        <p ng-show={{!field.isRequired}}>{{field.name}}: </p>
        <select ng-model="createChildResource[field.name]" class="form-control" style="width:auto; display: inline-block;">
            <option></option>
            <option ng-repeat="enumValue in field.enumValues" label={{enumValue.name}}>{{enumValue.ordinal}}</option>
        </select>
    </div>
</div>
<div class="preview">
    <p>Preview: </p>
    <textarea style="height:350px; width:550px; overflow:scroll;">{{createChildResource | json}}</textarea >
</div>
然后输出如下所示:

在这两种情况下,我都无法在textarea元素中编辑模型


如何做到这一点?我希望能够像中一样显示和编辑我的模型,但有一点不同:
editable textarea=“user.description”
应该是
editable textarea=“user”
,我终于明白了您想要实现的目标。在左侧有一组输入,在右侧(底部),有一个文本区域,将输入作为一个对象的属性进行排列,并将其格式化为对象

您的要求是允许用户编辑textarea中的属性值,从而更新输入中相应的属性值

首先,如注释所示,将对象转换为字符串,然后将其显示在textarea中

接下来,由于在更新textarea时需要响应和更新输入字段,因此需要查看textarea的值并更新原始对象(转换为字符串的对象)

这里使用一个示例,因为您的代码太复杂而无法理解,让我们假设您的对象
containerObject
,如下所示:

$scope.containerObject = {
    property_1: "Hello",
    property_2: "World"
};
$scope.getObjectAsText = function () {
    $scope.textAreaModel = JSON.stringify($scope.containerObject);
};
然后,您的输入将使用以下属性:

<input ng-model="containerObject.property_1">

<input ng-model="containerObject.property_2">
您的textarea标记将如下所示:

<textarea ng-model="textAreaModel"></textarea>
您需要使用
try…catch
异常处理程序块,因为用户可能会意外更改内容,从而在转换回object时,结果不是合适的对象(无效属性或无效语法)


只要只更改属性值,输入值就会正确更新。

您也可以将其包装成如下指令,或检查

Html

<div ng-app="app" ng-controller='userCtrl' >
    <textarea obj-edit obj="user" rows='10'></textarea>
    <p ng-bind='user.name'></p>
</div>
太好了。 下面是使用
ngModel
验证的代码

HTML

<form name="text">
   <textarea obj-edit ng-model="ctrl.json" name="json" rows="25" ng-model-options="{ debounce: 300 }"></textarea>
   <div class="alert alert-danger" role="alert" ng-show="text.json.$error.json">
        Error input
   </div>
</form>

createChildResource
是一个对象,因此在文本区域内显示为一个对象。尝试将对象转换为字符串-
JSON.stringify()
,您可能会看到其中的内容。我会尝试一下,并告诉您是否有用。ThxYes,现在我可以看到一个对象的内容,但我仍然无法更改它。你的意思是,更改没有反映在控制器或视图的其他区域,或者textarea被禁用,并且你无法编辑内容?视图是可以的,但是如果我尝试更改textarea-object字段中的任何内容,则不会更新。是的,您正确理解了目标和要求。在我看来,这个解决方案会很好地发挥作用。无论如何,谢谢你的巨大贡献。它澄清了一些问题。你的答案100%有用。我一有结果就会通知你。Thx:)我应该在哪里使用函数getObjectAsText()?我想在每个输入上都应该是ng change=“getObjectAsText()”?太好了,它帮助了我:)但仍然存在一个问题:与以前的字符串相比,textarea中的字符串格式很难看。你有没有想过如何处理这件事?如果你也能帮我的话,我会单独提出一个问题。这个问题解决了。非常感谢:)我的错-我最初打算在视图中使用
getObjectAsText()
作为模型,但后来改为使用
textAreaModel
。您可以在
ng change
指令中使用它,或者这次可以在对象上设置另一个
$scope.$watch()
,并调用
getObjectAsText()
在每次输入更改时更新textarea内容。是的,很好的解决方案:)很好。我在标准的
ngModel
中使用了
$parsers
$formatters
,进一步提高了性能
<div ng-app="app" ng-controller='userCtrl' >
    <textarea obj-edit obj="user" rows='10'></textarea>
    <p ng-bind='user.name'></p>
</div>
var app = angular.module("app", []);
app.controller('userCtrl', function($scope) {
    $scope.user= {name: 'ron', ocupation: 'coder'};
});
app.directive('objEdit', function() {
    return {
        restrict: 'A',
        scope: {
            obj:'=obj'
        }, 
        link: function(scope, element, attrs) {
            element.text(JSON.stringify(scope.obj, undefined, 2));
            element.change(function(e) {
                console.log(e.currentTarget.value);
                scope.$apply(function() {
                    scope.obj = JSON.parse(e.currentTarget.value);
                });
                console.log(scope.obj);
            })
        }
    }
})
<form name="text">
   <textarea obj-edit ng-model="ctrl.json" name="json" rows="25" ng-model-options="{ debounce: 300 }"></textarea>
   <div class="alert alert-danger" role="alert" ng-show="text.json.$error.json">
        Error input
   </div>
</form>
app.directive('objEdit', function() {
return {
    restrict: 'A',
    require: "ngModel",
    link: function(scope, element, attrs, ctrl) {
        ctrl.$formatters.push(function formatter(value) {
            return JSON.stringify(value, undefined, 2);
        });
        ctrl.$parsers.push(function(value) {
            try {
                var result = JSON.parse(value);
                ctrl.$setValidity('json', true);
                return result;
            } catch (e) {
                ctrl.$setValidity('json', false);
                return undefined;
            }
        });

    }
}});