2014-04-01 40 views
5

我希望能夠在<textarea>元素中編輯和顯示覆雜模型。下面是HTML片從JSON響應動態生成模型的字段:文字區域中的角JS顯示和編輯模型

<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> 

輸出如下:

enter image description here

但是,如果我嘗試將ngModel添加到textarea元素,能夠編輯這個值就像這樣:

<div class="preview"> 
    <p>Preview: </p> 
    <textarea ng-model="createChildResource" style="height:350px; width:550px; overflow:scroll;">{{createChildResource | json}}</textarea> 
</div> 

然後輸出如下:

enter image description here

在這兩種情況下,我不能在textarea元素編輯我的模型。

這是如何實現的?我希望能夠像this example那樣顯示和編輯我的模型,但略有不同:editable-textarea="user.description"應該是editable-textarea="user"

+1

'createChildResource'是一個對象,因此被示爲textarea的內部的物體。嘗試將對象轉換爲字符串 - 「JSON.stringify()」也許你應該看到內容。 – callmekatootie

+0

我會試一試,讓你知道它是否有幫助。 Thx – amenoire

+0

是的,現在我能夠看到一個對象的內容,但仍然無法改變它。 – amenoire

回答

9

我終於明白你在努力達到什麼目的。左邊有一堆輸入,右邊(底部)有一個textarea,它將輸入排列爲一個對象的屬性,並將它們顯示爲對象的格式。

您的要求是允許用戶編輯textarea中的屬性值,從而更新輸入中的相應屬性值。

首先,如註釋,將對象轉換爲字符串,然後在textarea中顯示它。

接下來,由於需要在更新textarea時作出反應並更新輸入字段,因此需要watch textarea的值並更新原始對象(被轉換爲字符串的對象)。

使用的例子在這裏,因爲你的代碼過於複雜,難於理解,讓我們說,你有對象containerObject如下:

$scope.containerObject = { 
    property_1: "Hello", 
    property_2: "World" 
}; 

你投入那麼利用這些屬性:

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

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

現在,您希望在textarea中顯示此內容 - 您將首先將對象轉換爲字符串並如下顯示它:

$scope.getObjectAsText = function() { 
    $scope.textAreaModel = JSON.stringify($scope.containerObject); 
}; 

而且你的textarea的標識看上去象這樣:

<textarea ng-model="textAreaModel"></textarea> 

每次在輸入文本框改變數值,文本區域也得到更新。

現在,換一種方式。當您更改textarea的,有輸入文本框得到更新,您需要觀看弦模型(而不是對象模型):

$scope.$watch('textAreaModel', function() { 
    try { 
     $scope.containerObject = JSON.parse($scope.textAreaModel); 
    } catch(exp) { 
     //Exception handler 
    }; 
}); 

你需要有try...catch異常處理程序塊,因爲用戶可能會意外更改內容,以便在轉換回對象時,結果不是合適的對象(無效屬性或語法無效)。

只要屬性值被更改,輸入值就會正確更新。

+0

是的,你正確理解目標和要求。在我看來,這種解決方案將工作得很好。無論如何,謝謝你的貢獻。它清除了一些問題。你的答案是100%有用的。一旦我收到一些結果,我會盡快通知你。 Thx :) – amenoire

+0

我應該在哪裏使用函數getObjectAsText()? – amenoire

+0

我猜它應該是每個輸入上的ng-change =「getObjectAsText()」? – amenoire

4

你也可以把它包裝成指令像下面,或檢查jsfiddler

的Html

<div ng-app="app" ng-controller='userCtrl' > 
    <textarea obj-edit obj="user" rows='10'></textarea> 
    <p ng-bind='user.name'></p> 
</div> 

的JavaScript

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); 
      }) 
     } 
    } 
}) 
+0

是的,很好的解決方案:) – amenoire

+1

尼斯羅恩。我繼續在標準的'ngModel' [codepen](http://codepen.io/anon/pen/Bsnzt) – JustMaier

+0

@JustMaier中使用'$ parsers'和'$ formatters'來增加額外的一步,這很好, 謝謝! – Ron

3

Ron's answer是巨大的。 下面是一個使用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> 

的Javascript

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

    } 
}});