programing

사용자 지정 Angular 지시어를 통해 템플릿을 조건부로 적용하는 방법은 무엇입니까?

i4 2023. 3. 7. 21:06
반응형

사용자 지정 Angular 지시어를 통해 템플릿을 조건부로 적용하는 방법은 무엇입니까?

DEMO

다음 지시사항을 고려합니다.

angular.module('MyApp').directive('maybeLink', function() {
  return {
    replace: true,
    scope: {
      maybeLink: '=',
      maybeLinkText: '='
    },
    template: '<span>' + 
              '  <span ng-hide="maybeLink" ng-bind-html="text"></span>' +
              '  <a ng-show="maybeLink" href="#" ng-bind-html="text"></a>' +
              '</span>',
    controller: function($scope) {
      $scope.text = $scope.maybeLinkText.replace(/\n/g, '<br>');
    }
  }; 
});

이 디렉티브는 양쪽을 추가합니다.<span>및 그<a>(한 번에 1개만 표시됩니다)

디렉티브를 DOM에 추가하거나 둘 다 추가하지 않도록 하려면 어떻게 해야 합니까?


갱신하다

좋아, 그럼 내가 좀 더ng-if다음과 같이 합니다.

template: '<span>' + 
          '  <span ng-if="!maybeLink" ng-bind-html="text"></span>' +
          '  <a ng-if="maybeLink" href="#" ng-bind-html="text"></a>' +
          '</span>'

하지만 어떻게 하면 주변을 없앨 수 있을까?<span>이 경우?


업데이트 2

다음은 를 사용하는 명령어 버전입니다.$compile주변 환경이 없습니다.<span>단, 양방향 데이터 바인딩도 작동하지 않습니다.양방향 데이터 바인딩 문제를 해결하는 방법을 알고 싶습니다.좋은 생각 있어요?

DEMO

angular.module('MyApp').directive('maybeLink', function($compile) {
  return {
    scope: {
      maybeLink: '=',
      maybeLinkText: '='
    },
    link: function(scope, element, attrs) {
      scope.text = scope.maybeLinkText.replace(/\n/g, '<br>');

      if (scope.maybeLink) {
        element.replaceWith($compile('<a href="#" ng-bind-html="text"></a>')(scope));
      } else {
        element.replaceWith($compile('<span ng-bind-html="text"></span>')(scope));  
      } 
    } 
  }; 
});

를 사용할 수 있습니다.template 기능합니다.문서에 따르면:

템플릿을 나타내는 문자열 또는 tElementtAttrs(아래 컴파일 함수 api에서 설명) 2개의 인수를 사용하여 템플릿을 나타내는 문자열 값을 반환하는 함수로 템플릿을 지정할 수 있습니다.


function resolveTemplate(tElement, tAttrs) {

}

angular.module('MyApp').directive('maybeLink', function() {
  return {
    //...
    template: resolveTemplate,
    //...
  }; 
});

스코프 속성을 기반으로 동적 템플릿을 주입하는 가장 깨끗한 방법이라고 생각합니다.

angular.module('app')
.directive('dynamic-template', function () {
  return {
    template:'<ng-include src="template"/>',
    restrict: 'E',
    link: function postLink(scope) {
      scope.template = 'views/dynamic-'+scope.type+'.html';
    }
  };
})

마지막에 다음 버전을 생각해 냈습니다.

angular.module('MyApp').directive('maybeLink', function($compile) {
  return {
    scope: {
      maybeLink: '=',
      maybeLinkText: '='
    },
    link: function(scope, element, attrs) {
      scope.$watch('maybeLinkText', function(newText) {
        scope.text = newText.replace(/\n/g, '<br>');
      });

      scope.$watch('maybeLink', function() {
        var newElement;

        if (scope.maybeLink) {
          newElement = $compile('<a href="#" ng-bind-html="text"></a>')(scope);
        } else {
          newElement = $compile('<span ng-bind-html="text"></span>')(scope);
        }

        element.replaceWith(newElement); // Replace the DOM
        element = newElement;            // Replace the 'element' reference
      });
    }
  };
});

나는 사용할 것이다.ng-switch.

비슷한 것

 template: '<span ng-switch on="maybeLink">' + 
          '  <span ng-switch-when="http://www.yahoo.com" ng-bind-html="text"></span>' +
          '  <a ng-switch-when="http://google.com" href="#" ng-bind-html="text"></a>' +
          '</span>',

또는

 template: '<span ng-switch on="maybeLink">' + 
          '  <span ng-switch-when={{maybeLink.length == 0}} ng-bind-html="text"></span>' +
          '  <a ng-switch-when={{maybeLink.length > 0}} href="#" ng-bind-html="text"></a>' +
          '</span>',

그래서 이게 방향이에요.

Plunker

ng-if 를 같은 경우에 사용할 수 있습니다.

다음으로 작업 예를 제시하겠습니다.

Working Demo

지시 코드:

angular.module('MyApp').directive('maybeLink', function() {
  return {
    replace: true,
    scope: {
      maybeLink: '=',
      maybeLinkText: '='
    },
    template: '<span>' + 
              '  <span ng-if="!maybeLink.link" ng-bind-html="text"></span>' +
              '  <a ng-if="maybeLink.link" href="#" ng-bind-html="text"></a>' +
              '</span>',
    controller: function($scope) {
      $scope.text = $scope.maybeLinkText.replace(/\n/g, '<br>');
    }
  }; 
});

다음은 동적 업데이트를 제공하는 솔루션입니다.사용방법:

<a rewrite-as-span="true"></a>

<a rewrite-as-span="false"></a>

<a rewrite-as-span="yourFn()"></a>

기타.

app.directive('rewriteAsSpan', function($compile){
  return {
    restrict: 'A',
    template: '<span />',
    replace: true,

    // we transclude the element because when it gets replaced with the span
    // we want all the properties from the original element
    transclude: 'element',

    compile: function(tElement, tAttrs){

      return {
        post: function(scope, element, attrs, controller, transclude){
          var rewrittenEl, originalEl;

          transclude(scope, function(clone){
            originalEl = clone;
          });


          scope.$watch(attrs.rewriteAsSpan, function(value){
            if (value === undefined || value === true){
              if (!rewrittenEl){
                // lazy compile and cache the rewritten element
                transclude(scope, function(clone){
                  rewrittenEl = tElement;
                  rewrittenEl.html(clone.html());
                  // remove this directive because the $compile would get infinite
                  rewrittenEl.removeAttr('rewrite-as-span');
                  $compile(rewrittenEl)(scope);
                });

              }

              element.replaceWith(rewrittenEl);
              element = rewrittenEl;

            } else {
              element.replaceWith(originalEl);
              element = originalEl;
            }
          });

        }
      };
    }
  };
});

요점으로서의 코드와 사양

언급URL : https://stackoverflow.com/questions/18892793/how-to-conditionally-apply-a-template-via-custom-angular-directives

반응형