기본 옵션이있는 AngularJS 지시문


145

방금 angularjs로 시작하고 몇 가지 오래된 JQuery 플러그인을 Angular 지시문으로 변환하려고합니다. 속성에 옵션 값을 지정하여 재정의 할 수있는 (요소) 지시문에 대한 기본 옵션 세트를 정의하고 싶습니다.

다른 사람들 이이 작업을 수행 한 방식을 둘러 보았고 angular-ui 라이브러리에서 ui.bootstrap.pagination 은 비슷한 일을하는 것 같습니다.

먼저 모든 기본 옵션은 상수 객체에 정의됩니다.

.constant('paginationConfig', {
  itemsPerPage: 10,
  boundaryLinks: false,
  ...
})

그런 다음 getAttributeValue유틸리티 기능이 지시문 컨트롤러에 연결됩니다.

this.getAttributeValue = function(attribute, defaultValue, interpolate) {
    return (angular.isDefined(attribute) ?
            (interpolate ? $interpolate(attribute)($scope.$parent) :
                           $scope.$parent.$eval(attribute)) : defaultValue);
};

마지막으로 이것은 링크 함수에서 속성을 다음과 같이 읽는 데 사용됩니다.

.directive('pagination', ['$parse', 'paginationConfig', function($parse, config) {
    ...
    controller: 'PaginationController',
    link: function(scope, element, attrs, paginationCtrl) {
        var boundaryLinks = paginationCtrl.getAttributeValue(attrs.boundaryLinks,  config.boundaryLinks);
        var firstText = paginationCtrl.getAttributeValue(attrs.firstText, config.firstText, true);
        ...
    }
});

이것은 일련의 기본값을 바꾸고 싶어하는 것처럼 표준으로 사용하기에는 다소 복잡한 설정처럼 보입니다. 이 작업을 수행하는 다른 방법이 있습니까? 아니면 getAttributeValue이런 식으로 옵션과 구문 분석 옵션과 같은 유틸리티 기능을 항상 정의하는 것이 정상 입니까? 사람들이이 공통 과제에 대해 어떤 전략을 가지고 있는지 알고 싶습니다.

또한 보너스로 왜 interpolate매개 변수가 필요한지 확실하지 않습니다.

답변:


108

compile기능 을 사용할 수 있습니다 -속성이 설정되지 않은 경우 읽기-기본값으로 채 웁니다.

.directive('pagination', ['$parse', 'paginationConfig', function($parse, config) {
    ...
    controller: 'PaginationController',
    compile: function(element, attrs){
       if (!attrs.attrOne) { attrs.attrOne = 'default value'; }
       if (!attrs.attrTwo) { attrs.attrTwo = 42; }
    },
        ...
  }
});

1
감사! 왜 ui.bootstrap.pagination사물이 더 복잡한 방식으로 생각됩니까? 컴파일 기능을 사용하는 경우 나중에 변경 한 속성 변경 사항은 반영되지 않지만이 단계에서 기본값 만 설정 되었기 때문에 사실이 아닌 것으로 보입니다. 여기에 약간의 상충 관계가있을 것 같아요.
Ken Chatfield

3
@KenChatfield의 compile속성을 읽을 수 없으므로 값을 얻으려면 보간해야합니다 (표현식 포함). 그러나 속성이 비어있는 경우에만 확인하려면 보간 속성에 표현식이있는 문자열이 포함되기 전에 트레이드 오프없이 작동합니다.
OZ_

1
환상적인! 명확한 설명을 주셔서 대단히 감사합니다. 미래의 리더를 들어, '보간'매개 변수에 무엇에 대한 설명은 원래의 질문에 접선,하지만 ui.bootstrap.pagination예를 나는이 매우 유용 예를 발견 jsfiddle.net/EGfgH
켄 Chatfield

그 솔루션에 대해 대단히 감사합니다. link옵션 이 필요한 경우 옵션에서 함수를 계속 반환 할 수 있습니다 compile. 여기 문서
mneute

4
속성은 템플릿에서 전달 될 때 값이 필요하다는 것을 기억하십시오. 배열 fe를 전달하는 경우 attributes.foo = '["one", "two", "three"]'대신 대신 해야합니다.attributes.foo = ["one", "two", "three"]
Dominik Ehrenberg

263

=?지시문의 범위 블록에서 속성에 대한 플래그를 사용하십시오 .

angular.module('myApp',[])
  .directive('myDirective', function(){
    return {
      template: 'hello {{name}}',
      scope: {
        // use the =? to denote the property as optional
        name: '=?'
      },
      controller: function($scope){
        // check if it was defined.  If not - set a default
        $scope.name = angular.isDefined($scope.name) ? $scope.name : 'default name';
      }
    }
  });

4
=?1.1.x부터 사용 가능
Michael Radionov

34
속성이 값으로 허용 true하거나 false값으로 사용할 수 있다면 $scope.hasName = angular.isDefined($scope.hasName) ? $scope.hasName : false;대신 예를 사용하고 싶습니다 .
Paul D. Waite

22
참고 : 그것은 단지 두 방법은 예를 들어, 바인딩 작동 =?한 방법은 바인딩 있지만, @?.
Justus Romijn

20
템플릿에서만 가능합니다 : template : 'hello {{name || \ '기본 이름 \'}} '
Vil

4
컨트롤러 또는 link기능 에서 기본값을 설정해야합니까 ? 내 이해에 link따라 $scope.$apply()사이클을 피해야 하는 동안 할당 하면 안됩니까?
Augustin Riedinger

1

AngularJS v1.5.10을 사용하고 있으며 기본 속성 값을 설정 하는 데 preLink컴파일 기능 이 더 잘 작동한다는 것을 알았습니다 .

알림 :

  • attrs항상 또는 문자열 인 원시 DOM 속성 값을 보유합니다 undefined.
  • scope제공된 분리 범위 사양 ( / / / 등) 에 따라 구문 분석 된 DOM 속성 값 을 보유합니다 .=<@

요약 된 스 니펫 :

.directive('myCustomToggle', function () {
  return {
    restrict: 'E',
    replace: true,
    require: 'ngModel',
    transclude: true,
    scope: {
      ngModel: '=',
      ngModelOptions: '<?',
      ngTrueValue: '<?',
      ngFalseValue: '<?',
    },
    link: {
      pre: function preLink(scope, element, attrs, ctrl) {
        // defaults for optional attributes
        scope.ngTrueValue = attrs.ngTrueValue !== undefined
          ? scope.ngTrueValue
          : true;
        scope.ngFalseValue = attrs.ngFalseValue !== undefined
          ? scope.ngFalseValue
          : false;
        scope.ngModelOptions = attrs.ngModelOptions !== undefined
          ? scope.ngModelOptions
          : {};
      },
      post: function postLink(scope, element, attrs, ctrl) {
        ...
        function updateModel(disable) {
          // flip model value
          var newValue = disable
            ? scope.ngFalseValue
            : scope.ngTrueValue;
          // assign it to the view
          ctrl.$setViewValue(newValue);
          ctrl.$render();
        }
        ...
    },
    template: ...
  }
});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.