AngularJS如何在替换指令之前访问指令中的元素

时间:2014-01-20 17:41:52

标签: angularjs angularjs-directive

如何在模板覆盖内容之前从指令中获取input元素?

HTML

<div xxx>
  <input a="1" />
</div>

JS

app.directive('xxx', function(){
  return {
        restrict: 'A',
        template: '<p></p>',
        replace: true, //if false, just leaves the parent div, still no input
        compile: function(element, attrs) {

            console.log(element);

            return function (scope, iElement, iAttrs) {
            }
        }
    };
});

我在角度1.0.x上,我无法使用'=?'传递可选范围参数语法,我希望能够以非常灵活的方式覆盖指令的默认模板的一部分。而不是每次我计划通过指令时添加范围变量或属性,我希望能够提供要使用的整个元素。

修改 输入必须保留指令的范围,而不是父节点。

修改 我试图在指令中包含一个部分模板,该指令将覆盖实际模板的一部分。因此,我所包含的部分需要访问指令的范围而不是父级的。

更新 看来如果我不提供模板或模板URL,而是使用$ templateCache手动替换内容,我可以访问内部元素。我想让角度处理模板和替换,但只是希望能够在它们被替换之前自然地访问指令中的内容。

解决方案 Plunkr

HTML

  <body ng-controller="MainCtrl">
        <div editable="obj.email">
            <input validate-email="error message" ng-model="obj.email" name="contactEmail" type="text" />
        </div>
  </body>

JS

app.controller('MainCtrl', function($scope) {
  $scope.obj = {
    email: 'xxx'
  };
});

app.directive('editable', function($log){
    return {
        restrict: 'A',
        transclude: true,
        template: '<div ng-show="localScopeVar">{{value}}<div ng-transclude></div></div>',
        scope: {
          value: '=editable'
        },
        link: function(scope) {
          scope.localScopeVar = true;
        }
    };
});


app.directive('validateEmail', function($log){
    return {
        restrict: 'A',
        require: 'ngModel',
        scope: true,
        link: function(scope, el, attrs, ctrl) {
          console.log(attrs['validateEmail']);
        }
    };
});

1 个答案:

答案 0 :(得分:9)

我相信你正在寻找transclude功能(链接是1.0.8文档)。你可以看到发生了什么:

app.directive('xxx', function($log){
    return {
        restrict: 'A',
        transclude: true,
        compile: function(element, attrs, transclude) {

            $log.info("every instance element:", element);

            return function (scope, iElement, iAttrs) {

                $log.info("this instance element:", element);

                transclude(scope, function(clone){

                    $log.info("clone:", clone);

                });
            }
        }
    };
});