Jeff, it appears that your transcludes are facing the wrong direction.
The functionality of transcludes seems to be operating in a reverse manner compared to your expectations.
When you have a transcluding directive and insert content within it, the content is actually reading from the parent of the transclude directive rather than the directive itself.
In your scenario, considering :
<div ng-controller="parentController as parent">
<transcluding-directive>
{{ key }} {{ val }}
</transcluding-directive>
</div>
There exist two main issues here.
Firstly, ng-transclude resides as a sibling to the content it transcludes.
Both elements would inherit parent
as their parent scope.
The transcluded content does not fetch data from within the transcluding directive.
This separation avoids conflicts; if the transcluding directive shared property names with the transcluded content, it would overwrite the latter and lead to unexpected behavior.
In essence, behind the scenes, its functioning may resemble this:
<transcluding-directive></transcluding-directive>
<div>{{ transcludedContent }}</div>
Subsequently, the content gets extracted and appended to the node identified by
transcludingDirective.querySelector("[ng-transclude"])
.
This isn't an exact explanation of how it works, but it depicts the outcome (excluding custom compiling/transcluding routines within the directive).
The second error becomes apparent once you comprehend the first issue:
{{ label }} and {{ id }} within vm
are properties on vm
's $scope
object.
Since they do not exist in that specific $scope
, they are therefore undefined
, hence resulting in '' + 'and' + ''
within your templates.
You're generating an <li>
for each directive item, yet interpolating undefined
and undefined
for all items.
The directive written should ideally be either specialized (knowing how to construct such a list) or generic (receiving the list as input)
<specific-list-maker items="vm.list"></specific-list-maker>
or a composite directive which includes more general directives inside its template...
<specific-list items="vm.list"></specific-list>
<!-- specific-list.html -->
<generic-drawer>
<generic-toggle ng-repeat="item in items">{{ item.label }} {{ item.id }}</generic-toggle>
</generic-drawer>
This kind of composition aligns well with Angular (as well as Polymer and potentially future technologies like Web Components).
To demonstrate, I've implemented a project where elements filter down akin to:
<page-type-a></page-type-a>
<!-- page-type-a.html -->
<card-collection cards="page.items"></card-collection>
<!-- card-collection.html -->
<header ><!-- ... header stuff --></header>
<card ng-repeat="card in cards"></card>
<!-- card.html -->
<header><h1>{{ title }}</h1></header>
<blockquote>{{ content }}</blockquote>
<cite>{{ author }}</cite>
<page-type-b></page-type-b>
<!-- page-type-b.html -->
<card-collection cards="page.items"></card-collection>
Each component focuses solely on its assigned tasks.
While other methods could work (e.g., introducing "key" and "value" attributes, then extracting values for composing your internal list), attempting those extra steps might prove overly complex in this situation.