编译动态内容

我正在重新说明这个问题,因为我认为原文不太清楚。

基本上,我有一个'包装'指令,我试图动态添加属性到一个包装(transcluded)元素。 我可以得到这个工作,但Angular似乎并没有意识到一旦添加新的属性。

如果我使用$compile那么Angular会识别它们 - 但是以双重编译transcluded内容为代价,在这种情况下,它会使select标签中的options数量加倍。

下面是一个显示(与评论)我正在尝试的东西,以下代码对于那些可以查看代码并仅仅通过查看来提示答案的人来说:(注意 - 我的最终目的是检查自定义指令valid-form-group required属性的valid-form-group ,如果发现将它应用于包含的select标签)

HTML

<body ng-controller="MainCtrl">

  <form name="validationForm" novalidate>

    <valid-form-group class="form-group" ng-class="{'has-error': validationForm.validInfo.$error.required}" required>

      <select ng-model="data.option" ng-options="option.id as option.message for option in selectOptions" name="validInfo" id="validInfo">
        <option value="">-- Select a Question --</option>
      </select>

    </valid-form-group>

  </form>

</body>

JS

var app = angular.module('plunker', [])
  .controller('MainCtrl', function($scope) {
    $scope.selectOptions = [
      {id: 1, message: 'First option'}, 
      {id: 2, message: 'Second option'}, 
      {id: 3, message: 'Third option'}
    ];
  })
  .directive('validFormGroup', function($compile) {
    return {
      restrict: 'E',
      template: '<div><span ng-transclude></span></div>',
      replace: true,
      transclude: true,
      require: '^form',
      link: function(scope, element, attrs, ctrl) {

        if (attrs.required !== undefined) {

          var selectElement = angular.element(element.find('select'));
          // either of the below produce the same results
          selectElement.attr('ng-required', true);
          //selectElement.attr('required', true);

          // if the below is commented out it wont validate
          // BUT if it is left in it will recompile and add another 3 options
          $compile(selectElement)(scope); 
        }
      }
    };
  });

CSS

.has-error{
  border: solid 1px red;
}

请注意,这里的示例使用' required '(或ng-required )作为添加的属性来突出显示Angular无法识别它,除非编译。

任何帮助或意见,欢迎 - 有点失望,我不能得到这个工作,所以也许有一些根本的我失踪...

抢劫者应该帮助我想象我的问题。

编辑 - 对回复和评论的回复延迟表示歉意。 正如下面的评论或两条中所提到的,个人问题使我无法找到时间进行调查。


试试这个简单的指令:

.directive('validFormGroup', function($compile) {
    return {
        restrict: 'A',
        replace: false,
        require: '^form',
        compile: function (element, attr) {
            if (attr.required !== undefined) {
                var selectElement = element.find('select');
                // either of the below produce the same results
                selectElement.attr('ng-required', true);
                //selectElement.attr('required', true);
            }
        }
    };
});

并将其用作html属性:

<div valid-form-group class="form-group" ng-class="{'has-error': validationForm.validInfo.$error.required}" required>

      <select ng-model="data.option" 
      ng-options="option.id as option.message for option in selectOptions"
      name="validInfo" id="validInfo" >
<option value="">-- Select a Question --</option>
</select>
      <br/>
      <br/>Required invalid? {{validationForm.validInfo.$error.required||false}}
      <br/>
      <br/>

</div>

DEMO

说明

  • 我在这个解决方案中根本不使用transclude ,因为这个指令的目的只是在用范围编译之前修改html ,所以不需要过度复杂的transcluded内容。

  • 这里我处理compile功能而不是link功能。 compile函数是在链接到范围之前修改html的好地方。


  • 我只能猜测你所看到的是在指令初始化过程中双重编译的结果,这就是为什么你看到了两套选项。

    你可以通过在$ timeout中包装你的编译来解决这个问题,这将确保编译在指令初始化之外发生。 这是一个工作演示,并在指令代码下面:

    .directive('validFormGroup', function($compile, $timeout) {
      return {
        restrict: 'E',
        template: '<div><span ng-transclude></span></div>',
        replace: true,
        transclude: true,
        require: '^form',
        link: function(scope, element, attrs, ctrl) {
          if (attrs.required !== undefined) {
            var selectElement = angular.element(element.find('select'));
            $timeout(function(){
              selectElement.attr('ng-required', true);
              $compile(selectElement)(scope);
            });
          }
        }
      };
    });      
    

    PS通过在指令中使用隔离范围,然后检查您的transcluded input / select元素是否具有所需的属性集,可以实现类似的引导包装函数。 在隔离的作用域上定义一个函数来检查错误,并将此函数绑定到form-group ng-class has-error。 这样你就不必使用$ timeout。


    我想在这里提出一个不同的方法,我适应于动态验证。 为字段动态添加验证,减少每个字段的样板html代码,我为类似目的编写了指令。 请参阅示例指令的plunker链接... PLUNKER

    我已经为所有类型的字段编写了这样的指令:数字,文本,选择,textarea,bool,datepicker等......附加的plunker为您提供了文本和数字字段的示例。

    角度的魔术发生在下面的衬垫上:

      var newElem = angular.element(template);
      element.replaceWith(newElem);
      $compile(newElem)(scope);
    

    所有其他代码只是一些逻辑,如果其他部分..

    链接地址: http://www.djcxy.com/p/79877.html

    上一篇: Compiling dynamic content

    下一篇: Does instantiating a template instantiate its static data members?