如果我将name作为属性而不是标记,为什么指令不起作用?

时间:2014-10-26 14:32:32

标签: javascript angularjs

Angular documentation的示例中,可以通过将其名称作为属性放在<div>中来使用指令。给出的例子是

<div ng-controller="Controller">
  <div my-customer></div>
</div>

js看起来像

angular.module('docsSimpleDirective', [])
  .controller('Controller', ['$scope', function($scope) {
    $scope.customer = {
      name: 'Naomi',
      address: '1600 Amphitheatre'
    };
  }])
  .directive('myCustomer', function() {
    return {
      template: 'Name: {{customer.name}} Address: {{customer.address}}'
    };
  });

但是,在类似的示例中,在此处,如果我将html代码从<tree>更改为<div tree>,则代码将不再有效。

为什么不呢?

JS Fiddle的代码:

<div ng-app="myapp">
    <div ng-controller="TreeCtrl">
        <tree family="treeFamily">
            <p>{{ family.name }}</p>
        </tree>
    </div>
</div>


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

module.controller("TreeCtrl", function($scope) {
    $scope.treeFamily = {
        name : "Parent",
        children: [{
            name : "Child1",
            children: [{
                name : "Grandchild1",
                children: []
            },{
                name : "Grandchild2",
                children: []
            },{
                name : "Grandchild3",
                children: []
            }]
        }, {
            name: "Child2",
            children: []
        }]
    };
});

module.directive("tree", function($compile) {
    return {
        restrict: "E",
        transclude: true,
        scope: {family: '='},
            template:       
            '<ul>' + 
                '<li ng-transclude></li>' +
                '<li ng-repeat="child in family.children">' +
                    '<tree family="child">{{family.name}}</tree>' +
                '</li>' +
            '</ul>',
        compile: function(tElement, tAttr, transclude) {
            var contents = tElement.contents().remove();
            var compiledContents;
            return function(scope, iElement, iAttr) {
                if(!compiledContents) {
                    compiledContents = $compile(contents, transclude);
                }
                compiledContents(scope, function(clone, scope) {
                         iElement.append(clone); 
                });
            };
        }
    };
});

tree {
    margin-left: 20px;
    display: block;
}

2 个答案:

答案 0 :(得分:2)

这是因为指令中的restrict选项。

此处设置为e,表示仅匹配元素名称。

更多https://docs.angularjs.org/guide/directive

答案 1 :(得分:2)

restrict选项用于指定如何在页面上调用指令。调用指令有四种不同的方法,因此有四种有效的限制选项:

'A' - attribute - <span ng-sparkline></span>
'E' - element - <ng-sparkline></ng-sparkline>
'C' - class - <span class="ng-sparkline"></span>
'M' - comment - <!-- directive: ng-sparkline -->

在你的情况下它不起作用,因为它被定义为限制'E' - 元素。