Nice programing

중첩 된 객체를 사용할 때 AngularJS에서 재귀 템플릿을 어떻게 만들 수 있습니까?

nicepro 2020. 11. 4. 08:25
반응형

중첩 된 객체를 사용할 때 AngularJS에서 재귀 템플릿을 어떻게 만들 수 있습니까?


중첩 된 양식 요소 그룹을 포함하는 JSON 개체에서 동적으로 양식을 작성하려고합니다.

  $scope.formData = [
  {label:'First Name', type:'text', required:'true'},
  {label:'Last Name', type:'text', required:'true'},
  {label:'Coffee Preference', type:'dropdown', options: ["HiTest", "Dunkin", "Decaf"]},
  {label: 'Address', type:'group', "Fields":[
      {label:'Street1', type:'text', required:'true'},
      {label:'Street2', type:'text', required:'true'},
      {label:'State', type:'dropdown',  options: ["California", "New York", "Florida"]}
    ]},
  ];

ng-switch 블록을 사용해 왔지만 위의 Address 개체에서와 같이 중첩 된 항목을 사용할 수 없게됩니다.

여기 바이올린이 있습니다 : http://jsfiddle.net/hairgamiMaster/dZ4Rg/

이 중첩 문제에 가장 잘 접근하는 방법에 대한 아이디어가 있습니까? 감사합니다!


나는 이것이 당신을 도울 수 있다고 생각합니다. 트리의 재귀 요소에 대해 Google 그룹 에서 찾은 답변 입니다.

제안은 Brendan Owen에서 제공합니다 : http://jsfiddle.net/brendanowen/uXbn6/8/

<script type="text/ng-template" id="field_renderer.html">
    {{data.label}}
    <ul>
        <li ng-repeat="field in data.fields" ng-include="'field_renderer.html'"></li>
    </ul>
</script>

<ul ng-controller="NestedFormCtrl">
    <li ng-repeat="field in formData" ng-include="'field_renderer.html'"></li>
</ul>

제안 된 솔루션은 현재 요소에 자식이있는 경우 ng-include 지시문을 사용하여 자신을 호출하는 템플릿을 사용하는 것입니다.

귀하의 경우에는 ng-switch 지시문 (당신처럼 레이블 유형 당 하나의 케이스)을 사용하여 템플릿을 만들고 자식 레이블이 있으면 끝에 ng-include를 추가하려고합니다.


@jpmorin과 @Ketan이 제안한 것을 결합하면 (실제로는 작동하지 않기 때문에 @jpmorin의 답변에 약간의 변경이 있음) ... ng-if"잎 자식"이 불필요한 ng-repeat지시문 을 생성하지 못하도록 방지 하는 방법 이 있습니다 .

<script type="text/ng-template" id="field_renderer.html">
  {{field.label}}
  <ul ng-if="field.Fields">
      <li ng-repeat="field in field.Fields" 
         ng-include="'field_renderer.html'">
      </li>
  </ul>
</script>
<ul>
  <li ng-repeat="field in formData" ng-include="'field_renderer.html'"></li>
</ul>

여기 Plunker 의 작동 버전이 있습니다.


ng-switch를 사용하여 Fields 속성의 가용성을 확인하는 것이 좋습니다. 그렇다면 해당 조건에 대해 다른 템플릿을 사용하십시오. 이 템플릿에는 Fields 배열에 ng-repeat가 있습니다.


나는 이것이 오래된 질문이라는 것을 알고 있지만 검색을 통해 여기에 올 수있는 다른 사람들에게는 나에게 다소 깔끔한 해결책을 남길 것입니다.

동일한 아이디어를 기반으로하지만 템플릿 캐시 등에 템플릿을 저장하는 대신 더 "깨끗한"솔루션을 원했기 때문에 결국 https://github.com/dotJEM/angular-tree 를 만들었습니다.

사용하기 매우 간단합니다.

<ul dx-start-with="rootNode">
  <li ng-repeat="node in $dxPrior.nodes">
    {{ node.name }}
    <ul dx-connect="node"/>
  </li>
</ul>

지시문은 컴파일 대신 transclusion을 사용하므로 (최신 버전 기준) ng-include 예제보다 성능이 더 좋습니다.

여기 데이터를 기반으로 한 예 :

angular
  .module('demo', ['dotjem.angular.tree'])
  .controller('AppController', function($window) {

    this.formData = [
      { label: 'First Name', type: 'text', required: 'true' },
      { label: 'Last Name',  type: 'text', required: 'true' }, 
      { label: 'Coffee Preference', type: 'dropdown', options: ["HiTest", "Dunkin", "Decaf"] }, 
      { label: 'Address', type: 'group',
      "Fields": [{
        label: 'Street1', type: 'text', required: 'true' }, {
        label: 'Street2', type: 'text', required: 'true' }, {
        label: 'State',   type: 'dropdown', options: ["California", "New York", "Florida"]
      }]
    }, ];

    this.addNode = function(parent) {
      var name = $window.prompt("Node name: ", "node name here");
      parent.children = parent.children || [];
      parent.children.push({
        name: name
      });
    }

    this.removeNode = function(parent, child) {
      var index = parent.children.indexOf(child);
      if (index > -1) {
        parent.children.splice(index, 1);
      }
    }

  });
<div ng-app="demo" ng-controller="AppController as app">

   <form>
        <ul class="unstyled" dx-start-with="app.formData" >
            <li ng-repeat="field in $dxPrior" data-ng-switch on="field.type">
                <div data-ng-switch-when="text">
                    <label>{{field.label}}</label>
                    <input type="text"/>
                </div>
                <div data-ng-switch-when="dropdown">
                    <label>{{field.label}}</label>
                    <select>
                        <option ng-repeat="option in field.options" value="{{option}}">{{option}}</option>
                    </select>
                </div>
                <div data-ng-switch-when="group" class="well">
                    <h2>{{field.label}}</h2>
                    <ul class="unstyled" dx-connect="field.Fields" />
                </div>   
            </li>
        </ul>
            <input class="btn-primary" type="submit" value="Submit"/>
    </form>
  
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
  <script src="https://rawgit.com/dotJEM/angular-tree-bower/master/dotjem-angular-tree.min.js"></script>

</div>


속성 기반 구조의 경우 jpmorin 게시물을 확장하고 싶습니다.

 JSON:
{
          "id": 203,
          "question_text_id": 1,
          "yes": {
            "question_text_id": 25,
            "yes": {
              "question_text_id": 26
            }
          },
          "no": {
            "question_text_id": 4
          }
        }

보시다시피 json 객체에는 배열 구조가 포함되어 있지 않습니다.

HTML

<div>
    <script type="text/ng-template" id="tree_item_renderer.html">
        <span>{{key}} {{value}}</span>
        <ul>
            <li ng-repeat="(key,value) in value.yes" ng-include="'tree_item_renderer.html'"></li>
            <li ng-repeat="(key,value) in value.no" ng-include="'tree_item_renderer.html'"></li>
        </ul>
    </script>

    <ul>
        <li ng-repeat="(key,value) in symptomeItems" ng-include="'tree_item_renderer.html'"></li>
    </ul>
</div>

그러나 반복 할 수 있습니다.

여기 에 속성에 대한 ng-repeat에 대한 Angular 문서

그리고 여기에 일부 행 구현

참고URL : https://stackoverflow.com/questions/15661289/how-can-i-make-recursive-templates-in-angularjs-when-using-nested-objects

반응형