2015-01-16 5 views
0

사용자가 버튼을 클릭 할 때 동적으로 추가하려는 지시문에 몇 가지 문제가 있습니다. 이것을 달성하기위한 최선의 방법은 무엇입니까?AngularJS에 동적으로 지시문을 추가하십시오.

내 연구에서 element.bind (jqLite 출신)을 찾았지만 인터넷에서 많은 예제를 찾지 못했습니다. 사전에

.directive('addattributes', function() { 
return { 
    restrict: 'E', 
    scope: { 
     attributes: '=options', 
     attr: '=' 
    }, 
    template: 
    '<div ng-class="classInput">' + 
    ' <div class="col-md-8" style="padding-left: 0;">' + 
    '  <label>Nome do Atributo</label>' + 
    '  <input type="text" class="form-control" placeholder="Attrs name" ng-model="attrname" ng-change="validation()">' + 
    ' </div>' + 
    ' <div class="col-md-4" style="padding-right: 0;"> ' + 
    '  <label>Tipo do Atributo</label> ' + 
    '   <select class="form-control" ng-options="attribute.name for attribute in attributes" ng-model="attrtype"></select>' + 
    ' </div> '+ 
    ' <div class="clearfix"> '+ 
    ' <div> '+ 
    ' <button type="button" class="btn btn-default btn-xs pull-right" ng-click="changeButton()" style="margin-top: 1em;" ng-show="showBtn == true"> Adicionar </button>  ' + 
    ' </div> {{attr}}'+ 
    '</div>', 
    link: function(scope,element,attrs){ 
     scope.showBtn = true; 
     scope.classInput = 'form-group'; 
     scope.attrtype= scope.attributes[2]; 

     scope.changeButton = function(){ 
      scope.showBtn = false; 
      scope.attr = { 
       name: scope.attrname, 
       type: scope.attrtype 
      }; 
     } 

     scope.validation = function(){ 
      if(scope.attrname.length < 6) { 
       scope.classInput = 'form-group has-error'; 
      } else { 
       scope.classInput = 'form-group has-success'; 
      } 
     } 


    } 
};}) 

감사합니다 좋은 하루


HTML 코드

<div class="form-group"> 
    <button class="btn btn-info" ng-click="addAttr()">Add Atributtes</button> 
</div> 
<addattributes options="attributes" attr="obj"></addattributes> 


AngularJS와 지시했다 :

여기 내 코드입니다!

+0

'addAttr() '함수가 무엇을합니까 ? –

+0

아직 아무것도, 그 기능을 html을 추가 할 것이라고 :) –

+0

나는 그것을 읽을 수 있지만 컨트롤러에서 DOM을 조작 안티 패턴입니다. –

답변

1

사용 사례에 대한 세부 정보를 제공하지 않고도 실현하려는 대상이로 더 간단하게 (더 중요한 것은 더 직관적으로) 이루어질 수 있는지 여부를 알기 어렵습니다., ng-switch 또는 기타 ng- 지시어를 사용하지만 사용자의 접근 방법을 충분히 고려했다고 가정합니다.

@New Dev는 이미 다른 답변에서 지적했듯이 DOM 조작을 컨트롤러가 아닌 지시문 안에 유지해야합니다. 이는 테스트 가능성, 관심사 분리 및 기타 여러 가지 작업에 도움이됩니다.

아래 코드는 간단한 방법으로보기가 너무 복잡해 보이기 때문에 추상적 인 방법으로 수행하려는 작업을 보여줍니다.

  1. 링크를에 컴파일 요소를 요소를 작성하고 DOM
  2. 에 추가 : 당신의 지시어는이 세 단계 과정 추가 newDirective라는 요소 인 경우


    범위

지시어의 링크 기능에서이 작업을 수행해야합니다. 요소에 액세스 : 지시어의 compile 기능이 링크 기능을 반환하기 때문에 컴파일 & 링크가 실제로 한 줄에서 두 단계입니다

link: function (scope, element, attributes) {  
    scope.addDirective = function() { 
    // create the new directive element 
    $newDirective = angular.element('<new-directive>'); 
    // Append it to the DOM 
    element.append($newDirective); 
    // compile it and link it to the scope 
    $compile($newDirective)(scope); 
    } 
} 

참고.

아래의 실행 가능한 코드 스 니펫을 참조하십시오. myDirectivenewDirective을 더합니다. newDirective 님의 템플릿에 제거 버튼이 있습니다. 제거 버튼을 클릭하면 링크 기능이 실행되었고 지시문이 올바르게 작동하고 있음을 증명합니다.

angular.module('app', []) 
 
.directive('myDirective', function ($compile){ 
 
    return { 
 
    restrict: 'E', 
 
    template: '<button ng-click="addDirective()">Click me!</button>', 
 
    link: function (scope, element, attributes) {  
 
     scope.addDirective = function() { 
 
     // create the new directive element 
 
     $newDirective = angular.element('<new-directive>'); 
 
     // Append it to the DOM 
 
     element.append($newDirective); 
 
     // compile it and link it to the scope 
 
     $compile($newDirective)(scope); 
 
     } 
 
    
 
    } 
 
    } 
 
}) 
 
.directive('newDirective', function ($compile){ 
 
    return { 
 
    restrict: 'E', 
 
    template: '<li>{{someText}}' + 
 
     '<button ng-click="remove()">Remove</button>' + 
 
    '</li>', 
 
    link: function (scope, element, attributes) { 
 
     scope.someText = "If the scope is linked this will show"; 
 
     scope.remove = function() { 
 
     element.remove() 
 
     } 
 
    } 
 
    } 
 
});
<script 
 
    src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"> 
 
</script> 
 

 
<div ng-app="app"> 
 
    <my-directive></my-directive> 
 
</div>

+0

그건 내 문제를 해결, 감사합니다! –

+0

에드, 나는 지시어가 당신이 할 수있는 것처럼 Angular의 패러다임으로 재사용해야하는 다른 지시어를 추가한다고 카운터 할 것이고, 단지'가 다음과 같을 수도 있기 때문에'ng-repeat '을 사용할 것입니다. 상위 디렉티브를 통해 페이지 컨트롤러에서 오는 데이터로 무언가를 할 필요가있다 –

+0

@NewDev 가능하다면'ng-'지시어를 사용해야한다는 것은 당신의 정서에 절대적으로 동의한다. 이 예제는 인위적이며 지나치게 단순화되었지만 ** 지시문을 ** 추가 및 컴파일하는 방법 **을 실제로 ** 시연하는 것이 었습니다. 즉,''는'ng-repeat'을 사용하는 것과 마찬가지로 부모 컨트롤러의 데이터에 액세스 할 수 있습니다. –

2

컨트롤러에 "지시문 추가"를하지 마십시오. 이것은 DOM을 조작한다는 것을 의미합니다.

대신 ViewModel을 생각해보십시오. 이 지시어는 어떤 ViewModel 속성을 표시/변경합니까? 그것이 "속성"이라면, attributes 속성과의 이름 충돌을 피하기 위해 attribute$scope.myAttributes에 추가하십시오.

$scope.myAttributes = []; 
$scope.addAttr = function(){ 
    $scope.myAttributes.push({}); // empty object to hold some property of an "attribute" 
} 

다음,보기, ng-repeatattributes 이상에서 :

<div class="form-group"> 
    <button class="btn btn-info" ng-click="addAttr()">Add Atributtes</button> 
</div> 
<addattributes ng-repeat="attribute in myAttributes" attr="attribute"></addattributes> 

는 (나는 완전히 addattributes 지시어가 무엇을 이해하지 못하는, 그래서 나는 attr를 통해 속성 오브젝트를 설정 있으리라 믿고있어)

+0

그의 질문에서 그는 컨트롤러에서 DOM을 조작하고 싶다고 말했습니까? 이 질문은 지시문을 포함하고 있기 때문에 하나의 지시문에 또 다른 지시문을 추가하는 것이 완벽하게 허용됩니다. 모든 것이'ng-repeat '으로 끝나지는 않습니다. –

+0

@EdHinchliffe, 지시어를 추가하는 지시어가 아닙니다. 컨트롤러에서 정의 된 addAttr 함수를 사용하여 지시문 외부의 버튼을 클릭하는 것입니다. 그의 질문과 그의 대답에 대한 나의 의견을 읽으십시오. –

+0

아, 맞습니다. 그러나 'addAttr'을 호출하는 HTML은 지시문 템플릿 내에 있으므로 단순히 함수를 링크 함수로 옮길 수 있습니다. –

관련 문제