angular directive transclusion and inheritance

ぃ、小莉子 提交于 2019-12-11 05:05:14

问题


I've got three directives:

aiOutter, aiMiddle, and aiInner.

app.directive('aiOutter', function() {
  return {
    restrict: 'A',
    scope: {
      data: '='
    },
    template: '<div>Outter: {{data}}</div>',
    transclude: true,
    link: function(scope, elem, attrs) {
      console.log('outter recognized');
      return console.log('outter data:', scope.data);
    }
  };
}).directive('aiMiddle', function() {
  return {
    restrict: 'A',
    scope: {
      data: '='
    },
    template: '<div>Middle: {{data}}</div>',
    transclude: true,
    link: function(scope, elem, attrs) {
      console.log('middle recognized');
      return console.log('middle data:', scope.data);
    }
  };
}).directive('aiInner', function() {
  return {
    restrict: 'A',
    scope: {
      data: '='
    },
    template: '<div>Inner: {{data}}</div>',
    link: function(scope, elem, attrs) {
      console.log('inner recognized');
      console.log('inner data:', scope.data);
      scope.changeData = function(newData) {
        scope.data = newData;
      }
    }
  };
});

My markup looks like the following:

<body ng-controller="MainCtrl">
    <div ai-outter data="name">
      <div ai-middle data="data">
        <div ai-inner data="data">
        </div>
     </div>
   </div>

Only the outter most directive seems to be picked up. What do I need to do to be able to use this inheritance pattern as well as be able to populate the inner-most directive with transcluded markup?

Plunker: http://plnkr.co/edit/HvaJKmGH2agEOKHGrZvV

EDIT Clarification

I edited my markup a as suggested by PascalPrecht (the updated plunker is here: http://plnkr.co/edit/HvaJKmGH2agEOKHGrZvV )

<body ng-controller="MainCtrl">
    <div ai-outter data="name" ng-transclude>
      <div ai-middle data="name" ng-transclude>
        <div ai-inner data="name" ng-transclude>
         <h1> Hello, {{name}}</h1>
         <button ng-click="name = 'bob'">Click me</button>
        </div>
      </div>
    </div>

However, I think I'm running into a scoping issue. When I push the button, the {{name}} model should bind all the way back up, should it not? Currently, only the inner-most scope is being updated.

I think I'm confused about scoping when it comes to directives.


回答1:


You can't use a primitive value and you should reference an object from your scope's controller.

See a modified version of your code: http://plnkr.co/edit/666Adad72zRJIasOzurs?p=preview

And be sure to check out this excellent answer: What are the nuances of scope prototypal / prototypical inheritance in AngularJS?




回答2:


You need to specify ng-transclude within your directives template to tell angular, where to put transcluded content. You could then do some chaining, by providing a template that gets transcluded content, where as the transcluded content again contains a directive that gets data that is two-way bound.

I updated your plunk accordingly: http://plnkr.co/edit/sM3Jnj?p=preview



来源:https://stackoverflow.com/questions/18794968/angular-directive-transclusion-and-inheritance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!