Angularjs inherits scope in nested directives

example in: http://jsfiddle.net/avowkind/PS8UT/

I want the directive of the nested child element to get its data from the parent directive of the shell, if present, otherwise from an external controller.

<div ng-controller="MyCtrl">
    <parent index="1">
        <child></child>
    </parent>
    <parent index="2">
        <child></child>
    </parent>
     <h1>No Parent</h1>
    <child></child>
</div>
<hr>

Required conclusion

Parent 1
  Child of parent 1
Parent 2
  Child of parent 2
No Parent
  Child of parent 0

Currently, my child sees only the external value of the controller:

Actual output

Parent 1
  Child of parent 0
Parent 2
  Child of parent 0
No Parent
  Child of parent 0

This is a simple version; in reality, external directives receive data from a server that is formatted by a nested child, so the passed object is a complex object, not a simple string. In addition, the child is a visualization that will work on different data sets, so the external directive of the parent element is not always the same type.

, , , , .

<temperature-for city="Auckland">
   <plot/>
   <analysis/>
</temperature-for>

<humidity-for city="Hamilton">
   <plot/>
   <analysis/>
</temperature-for>


<test-data>
   <plot/>
</test-data>
+4
3

, , , .

, , . :

<plot data="countries['Auckland'].plot.data" options="countries['Auckland'].plot.options" legend="external" zoom="xy"></plot>

Scope would look like:
scope: {
    data: '=',
    options: '=',
    zoom: '@?',  // '?' indicates optional
    legend: '@?',
}

, , , .

, , AngularJS, , .

: : HTML, , , - (, ? ?)

+3

, , , , .

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

function MyCtrl($scope) {
  $scope.index = 0;
}

myApp.directive('parent', function () {
  return {
    transclude: true,
    scope: {
      index: '='
    },
    restrict: 'EA',
    template: '<h2>Parent {{ index }}</h2>',
    compile: function(tE, tA, transcludeFn) {
      return function (scope, elem, attrs) {
        elem.append(transcludeFn(scope)[1]);
      };
    }
  }
});

myApp.directive('child', function () {
  return {
    restrict: 'EA',
    scope: false,
    template: '<p>Child of parent {{ index }}</p>'
  }
});

.

, , ngTranscludeDirective , . , , , .

, (, , ).

, , .

. , .

, 5:

link: function(scope) {
  scope.index = 5;
}

scope.items , . ( MyCtrl). MyCtrl.

:

link: function(scope) {
  scope.somethingElse = foo;
}

scope.somethingElse , .

+2

, ng-transclude: http://jsfiddle.net/PS8UT/2/

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

function MyCtrl($scope) {
    $scope.index = 0;
}

myApp.directive('parent', function ($compile) {
    return {
        scope: {
            index: '@'
        },
        restrict: 'EA',
        transclude: true,
        template: '<h2>Parent {{ index }}</h2>',
        link: function (scope, elem, attrs, ctrl, transclude) {
            transclude(scope, function(clone, s){
                elem.append($compile(clone)(s)); // basically you need to reassign the inner child scope to your current isolated scope
            });
        }
    }
});

myApp.directive('child', function () {
    return {
        //scope: true, // no need to create another scope since you want to use the parent
        // scope: { }, // no index printed
        restrict: 'EA',
        template: '<p>Child of parent {{ index }}</p>'
    }
});

, , , . ng-transclude , . angular docs $compile docs :

transclude . ngTransclude. , . , , , . , , , ( ) .

0

Source: https://habr.com/ru/post/1534519/


All Articles