2013-05-06 2 views
1

유연한 스프레드 시트 형식 데이터 입력 폼을 표시하는 데 사용하려는 일반 지시문을 만들려고합니다.자식 요소에서 데이터 추출 및 지시문에서 사용

모든 데이터 구조를 & HTML 코드에 입력하고 지시문을 가져 와서 나중에 사용할 수 있도록 범위에 저장하고 싶습니다. 여기

내가 사용하고 싶습니다 샘플 HTML의 (이하 "필드"요소의 정보 것은 내가 범위에 들어가하고 싶은 것입니다) :

<array title="Breakdown" data="data.breakdown"> 
    <field type="text" default="" name="descr">Description</field> 
    <field type="number" default="0" name="price">Price</field> 
    <field type="number" default="0" name="tax">Tax</field> 
</array> 

그리고 지침까지

.directive('array', function(){ 
    return { 
    restrict: "E", 
    replace: true, 
    transclude: true, 
    templateUrl: "js/array-template.html", 
    compile: function(tElement, tAttrs, transclude) { 
     var x=transclude(tElement);    
     return function(scope, element, attrs) { //the linking function 
     scope.title=attrs.title; 
     } 
    } 
    } 
} 

변수 x는 나에게 html 요소 배열을 제공하지만 "필드"요소뿐만 아니라 빈 "span"요소도 포함합니다. 필요한 경우 작업 할 수 있지만 더 간단한 방법이 있다고 생각합니다.

+0

처음으로

<!DOCTYPE html> <html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body ng-app="flexlist"> <array title="Breakdown" data="record"> <field type="text" default="" name="descr" title="Description"></field> <field type="number" default="0" name="price" title="Price"></field> <field type="number" default="0" name="tax" title="Tax"></field> </array> <array title="test" data="record"> <field type="text" default="" name="descr" title="Description"></field> </array> </body> <script src="js/angular.js"></SCRIPT> <script src="js/controller.js"></SCRIPT> </html> 

자바 스크립트는 linkingFunction입니다. 또한 요소에 접근 할 수 있으므로 이론적으로 요소를 검색하고 값을 가져 와서 범위에 할당 할 수 있습니다. 그러나 이것은 지저분한 느낌입니다. JSON과 같은 더 나은 형식으로 데이터를 가져올 수 있습니까? 그렇다면 지시어에 특성으로 전달할 수 있고 필요한 값을 가져 와서 필요한 항목을 템플릿에 삽입 할 수 있습니다. – bennick

+0

@bennick 감사합니다. 그렇습니다. 해결책이 될 수는 있지만 바람직하지는 않습니다. 다른 구문을 HTML 마크 업과 혼합하는 것입니다. 나는 엘리먼트에 대한 설명을 HTML로 유지하려고했다. 많은 검색을 한 후에 솔루션을 찾아서 게시했습니다. –

답변

0

솔루션을 찾았습니다!

먼저 나는 AngularJS와 웹 사이트 메인 페이지의 마지막 예제를 사용했습니다 : 나는 <FIELD>을 위해 NG-transclude 지시어를 사용했기 때문에 시작 좋았다 그러나 렌더링 된 HTML 코드는 항상 어떤 쓰레기를 포함 http://angular.github.io/angularjs.org/#/list 처리 된 요소들.

그래서 더 자세히 살펴본 결과 동적으로 생성 된 템플릿 생성의 몇 가지 예가 발견되었습니다. 그렇게하면 훨씬 더 많은 유연성을 얻을 수 있으며 결과 코드에 낡은 조각이 나타나지 않고도 HTML을 완전히 다시 작성할 수 있습니다.

AngularJS 웹 사이트 (공유 컨트롤러)에서 사용 된 방법이 주 지시문의 템플릿에 ng-transclude가 사용되지 않았을 때 고장 났기 때문에 지시어간에 다른 통신 방법을 사용해야했습니다. 두 개의 지시문이 모두 같은 객체에 속하기 때문에 모듈 객체에 추가 된 속성 만 사용했습니다.

다음은 솔루션의 전체 코드입니다. 나는 그것이 어떤 사람들에게는 도움이되기를 바랍니다.

HTML : 당신이 범위에 액세스 할 수 있습니다 충분한 의견 ;-)

function record(){ //a simple constructor to provide the data for the table 
    return [{ 
      descr: "example", 
      price: 10, 
      tax: 0.07 
     }, 
     { 
      descr: "something else", 
      price: 15, 
      tax: 0.11 

     } 
    ]; 
} 

var mod=angular.module('flexlist', []); 
mod.fields=[]; //container that is shared between directives 
//the directive for <ARRAY> 
mod.directive('array', function($compile){ //injecting the $compile service 
    return { 
     restrict: 'E', //restricted to element only 
     replace: true, 
     scope:{ 
      title: '@title' //getting the title attribute into the scope 
     }, 
     link: function(scope,element,attr){ 
      //calling the function specified in the "data" attribute 
      //which should return the data to be filled into the table 
      scope.source=window[attr.data](); 
      scope.fields=[]; //preparing the "field" variable in the scope 
      //copying the data collected from the <field> elements into the scope 
      angular.copy(mod.fields,scope.fields); 
      //preparing the collection for the next use 
      //(in case more than one <ARRAY> block is in a page 
      mod.fields=[]; 
      newCont=angular.element( //creating the template's HTML 
'<FIELDSET>'+ 
    '<LEGEND>{{title}}</LEGEND>'+ 
    '<TABLE border=1>'+ 
     '<TR>'+ 
      '<TH ng-repeat="fld in fields">{{fld.title}}</TH>'+ 
     '</TR>'+ 
     '<TR ng-repeat="line in source">'+ 
      '<TD ng-repeat="fld in fields">{{line[fld.name]}}</TD>'+ 
     '</TR>'+ 
    '</TABLE>'+ 
'</FIELDSET>'); 
      //applying the Angular "magic" -- the directives in the template 
      $compile(newCont)(scope); 
      element.replaceWith(newCont); //replace the whole <ARRAY> element 
     }, 
     controller: function($scope, $attrs){ 
      // nothing here yet 
     } 
    }; 
}); 

mod.directive('field',function(){ 
    return { 
     require: '^array', //the "^" means that <FIELD> has to be inside <ARRAY> 
     restrict: 'E', //restricted to be an element only 
     link: function(scope,element,attrs){ //collecting the data from the element 
      mod.fields.push({ //pushing the data into the collection object 
       type: attrs.type, 
       'default': attrs['default'], 
       name: attrs.name, 
       title: attrs.title     
      }); 
     } 
    }; 
}); 
관련 문제