javascript - AngularJS: multiple directives with transclusion on same element -
i'm trying inject 2 templates element , operate on them:
<div ic-first="foo" ic-second="bar" ic-third="baz" ic-fourth="qux" > </div>
icfirst should inject via template empty div child of element. icsecond should inject second div (with bunch of content) second child of element, resulting html like:
<div ic-first="foo" // priority: 100 ic-second="bar" // priority: 50 ic-third="baz" // priority: 0 ic-fourth="qux" // priority: 0 > <div id="foo"></div> <div> <!-- bunch of stuff templateurl --> </div> </div>
both icfirst , icsecond inject other elements newly created containers.
when specify directive template property on both directives, error:
error: multiple directives [icfirst, icsecond] asking template on:
<div ic-first
…
when add transclude: true
both directives, icfirst executes fine…but other directives on same element not executed. when set transclude: 'element'
, other directives execute but error first child ($scope.firstobj
) undefined.
all 4 directives need access each other's scope, i'm doing of work in controllers:
app.directive('icfirst', ['ic.config', function (icconfig) { return { restrict: 'a', priority: 100, template: '<div id="{{firstid}}"></div>', replace: false, transclude: 'element', controller: function icfirst($scope, $element, $attrs) { // … $scope.firstid = $scope.opts.fooid; $scope.firstelm = $element.children()[0]; $scope.firstobj = {}; // used other 3 directives }, link: function(scope, elm, attrs) { … } // <- event binding } ); app.directive('icsecond', ['ic.config', function (icconfig) { return { restrict: 'a', priority: 0, templateurl: 'views/foo.html', replace: false, transclude: 'element', controller: function icsecond($scope, $element, $attrs) { // … $scope.secondelm = $element.children()[1]; $scope.secondobj = new bar( $scope.firstobj ); // ^ used remaining 2 directives & requires obj icfirst }, link: function(scope, elm, attrs) { … } // <- event binding } );
note have corrected behaviour of replace: false
match documented behaviour, described in pull request #2433.
i tried instantiating $scope.firstobj
in controller, , setting in linkfn (hoping transclusion have completed time linkfn executes), same problem. appears first-child comment.
the reason can come explains throwing error angularjs team trying avoid needless overwrites/dom manipulation:
considering actual behaviour of replace: false
vs documented behaviour, think actual in fact intended behaviour. if true, allowing multiple templates/templateurls used on same element cause subsequent templates overwrite previous ones.
since modified source match documented behaviour, quick fix†, modified source again (/src/ng/compile.js:700) remove assertnoduplicate
check (which corresponds angular.js:4624
). return following 2 objects, , works, , can't find negative repercussions:
// directive icfirst return { restrict: 'a', priority: 100, replace: false, template: '<div id="{{firstid}}"></div>', require: ["icfirst"], controller: controller, link: postlink }; // directive icsecond return { restrict: 'a', require: ['icfirst'], replace: false, templateurl: 'views/bar.html', priority: 50, controller: controller, link: postlink };
† if made permanent, check should be
if (directive.templateurl && directive.replace)
(and similar directive.template)
Comments
Post a Comment