我可以将范围变量传递给指令的链接函数,但不能传递编译函数angular

时间:2015-05-12 07:52:41

标签: angularjs angularjs-directive angularjs-scope

我使用ng-repeat,我需要将范围变量传递给指令的编译功能。我知道如何使用link函数,而不是编译函数。

我的HTML看起来像:

    <div ng-repeat="item in chapter.main">
      <block type="item.type"></block>
    </div>

让我们说item.type =&#34; blah&#34;无论物品。 然后这个链接功能正常

app.directive('block', function() {
  return {
      restrict: 'E',
      link: function(scope, element, attributes){
            scope.$watch(attributes.type, function(value){
                console.log(value); //will output "blah" which is correct
            });

        }
  }
});

但我不能对编译做同样的事情吗?

app.directive('block', function() {
  return {
      restrict: 'E',
      compile: function(element, attrs, scope) {
        scope.$watch(attrs.type, function(value){
             console.log(value);
         });
      }
  }
});

我得到的错误是&#34;无法读取属性$ watch of undefined&#34; ..

这就是我喜欢我的指示的方式:

app.directive('block', function() {
  return {
      restrict: 'E',
      compile: function(element, attrs) {
        element.append('<div ng-include="\'{{type}}-template.html\'"></div>');
        //or element.append('<div ng-include="\'{' + attrs.type + '}-template.html\'"></div>');
        //except the above won't interpret attr.type as a variable, just as the literal string 'item.type'
      }
  }
});

1 个答案:

答案 0 :(得分:2)

compile函数没有scope作为其参数。

function compile(tElement, tAttrs, transclude) { ... }

注意:最新版本的Angular中不推荐使用transclude。

您是否有任何理由不想使用link

来自DOC

  

编译函数处理转换模板DOM。由于大多数指令不进行模板转换,因此不经常使用。 compile函数采用以下参数:

     

tElement - template element - 声明指令的元素。仅对元素和子元素进行模板转换是安全的。

     

tAttrs - 模板属性 - 在所有指令编译函数之间共享的此元素上声明的规范化属性列表。

     

transclude - [DEPRECATED!]一个transclude链接函数:function(scope,cloneLinkingFn)

<强>更新

要从compile功能内部访问范围,您需要具有preLinkpostLink功能。在您的情况下,您只需要postLink功能。所以这......

compile: function compile(tElement, tAttrs, transclude) {
    return function postLink(scope, element, attrs) { ... }
},

提议的解决方案可能不准确,但应该帮助您。

<强> HTML

<div ng-app="myApp" ng-controller="app">
    <block type="item.type"></block>
</div>

JS(Controller + Directive)

var myApp = angular.module('myApp', []);

myApp.controller('app', function ($scope, $http) {
    $scope.item = {
        type: 'someTmpl'
    };
}).directive('block', ['$compile', function ($compile) {
    return {
        restrict: 'AE',
        transclude: true,
        scope: {
            type: '='
        },
        compile: function (element, attrs) {
            return function (scope, element, attrs) {
                var tmpl;
                tmpl = scope.type + '-template.html';

                console.log(tmpl);

                element.append('<div ng-include=' + tmpl + '></div>');

                $compile(element.contents())(scope);
            };
        }
    };
}]);