In Polymer 1.2, How do I use content in dom-repeat?.
//component
<dom-module id="data-stream">
<template>
...
<div class="data-stream-list">
<template is="dom-repeat" items="[[stream]]">
<div class="data-stream-item">
<content></content>
</div>
</template>
</div>
</template>
...
</dom-module>
//used as
<data-stream>
<!--// template for data stream item -->
<div class="custom-data-stream-item">[[item]]</div>
</data-stream>
Supposing i had a hypothetical stream of [one, two, three, four] this returns
...
<div class="data-stream-list">
<div class="data-stream-item">
<div class="custom-data-stream-item"></div>
</div>
<div class="data-stream-item"></div>
<div class="data-stream-item"></div>
<div class="data-stream-item"></div>
</div>
...
Implying the light DOM is stamped at least once but not repeated. Neither does there seem to be any binding. Not as expected.
That is just not supported. If you have several <content> elements without a selector, all children will be projected to the first <content> element.
If you add a select="someSelector" where someSelector is different for each <content> element and matches with a child each then it might work (not sure if dynamically added <content> elements are supported at all).
Related
I have three Angular component, one base component and two child component (child1 and child2), with these structure:
child1.component.html
<ng-template #child1Template>
<div>
<h1>CHILD 1</h1>
</div>
</ng-template>
child2.component.html
<ng-template #child2Template>
<div>
<h1>CHILD 2</h1>
</div>
</ng-template>
base.component.html
<app-child1 #wrapper_child1 class="hidden"></app-child1>
<app-child2 #wrapper_child2 class="hidden"></app-child2>
<div class="baseContainer">
<ng-content *ngTemplateOutlet="wrapper_child1.child1Template"></ng-content>
<ng-content *ngTemplateOutlet="wrapper_child2.child1Template"></ng-content>
</div>
When I inspect the DOM, it shows child1 correctly but child2 not appears and there is that
<!--bindings={
"ng-reflect-ng-template-outlet": "[object Object]"
}-->
Anyone has some explenation?
Please note that my structure absolutely needs this structure because I need to insert the content of childs in the base component WITHOUT adding additional html tags.
Thanks!
Thanks to Vovan_Super I solved my issue adding this line of code in childs component
#ViewChild('child1Template') child1Template: TemplateRef<any>;
I want to repeat a piece of HTML, multiple times in my template.
But I want it to be repeated at different places on my page. This means that ngFor is not the solution as the pieces would be repeated directly one after the other.
A 'working solution' would be to define a specific #Component for my repeated HTML, and do something like that :
<p>Whatever html</p>
<my-repeated-html></my-repeated-html>
<h4>Whatever</h4>
<my-repeated-html></my-repeated-html>
But I find it overkill to create a dedicated component for doing something like that, it has no functional meaning and is only required by the HTML structure I want to set up.
Is there really nothing in ng2 template engine to allow me to define an "inner template" and use it wherever I need it in the current template?
update Angular 5
ngOutletContext was renamed to ngTemplateOutletContext
See also https://github.com/angular/angular/blob/master/CHANGELOG.md#500-beta5-2017-08-29
original
The recently added ngTemplateOutlet might be what you want
<template [ngTemplateOutlet]="templateRefExpression" [ngOutletContext]="objectExpression"></template>
It can currently be used like
<template #templateRef>
<pre>{{self | json }}</pre>
</template>
<template [ngTemplateOutlet]="templateRef"></template>
A template can also be passed to a child component to be rendered there
#Component({
selector: 'some-child',
providers: [],
template: `
<div>
<h2>Child</h2>
<template [ngTemplateOutlet]="template" ></template>
<template [ngTemplateOutlet]="template" ></template>
</div>
`,
directives: []
})
export class Child {
#ContentChild(TemplateRef) template:TemplateRef;
}
to be used like
<some-child>
<template>
<pre>{{self | json }}</pre>
</template>
</some-child>
stackblitz example
Another Plunker example
that uses data passed as
<template [ngTemplateOutlet]="..." [ngOutletContext]="templateData"
This way ngOutletContext can be used in the template like
<template let-image="image">
{{image}}
where image is a property of templateData
If $implicit is used
<template [ngTemplateOutlet]="..." [ngOutletContext]="{$implicit: templateData}"
the ngOutletContext can be used in the template like
<template let-item>
{{item}}
<campaign-channels-list (onItemSelected)="_onItemSelected($event)" [customTemplate]="customTemplate" (onDragComplete)="_onDragComplete($event)" [items]="m_blockList"></campaign-channels-list>
<template #customTemplate let-item>
<a href="#" [attr.data-block_id]="item.blockID">
<i class="fa {{item.blockFontAwesome}}"></i>
<span>{{item.blockName}}</span>
<i class="dragch fa fa-arrows-v"></i>
<span class="lengthTimer hidden-xs">
{{item.length | FormatSecondsPipe}}
</span>
</a>
</template>
and in rx component:
<div class="sortableList">
<li (click)="_onItemSelected(item, $event, i)" *ngFor="let item of m_items; let i = index" class="listItems list-group-item" [ngClass]="{'selectedItem': m_selectedIdx == i}">
<template [ngTemplateOutlet]="customTemplate" [ngOutletContext]="{$implicit: item}">
</template>
</li>
</div>
pay attention to:
[ngOutletContext]="{$implicit: item}"
as well as
<template #customTemplate let-item>
Per the template below, I am trying to keep words from breaking using CSS white-space tags. The problem is Polymer seems to automatically close the open tags I am using as the wrapper. Any help?
<template is="dom-repeat" items="{{getHiddenStrArr(diffObj.value)}}" as="char" >
<template is="dom-if" if="{{!index}}">
<together>[
</template>
<template is="dom-if" if="{{!isASpace(char)}}">
<span class="added-char">{{char}}</span>
</template>
<template is="dom-if" if="{{isASpace(char)}}">
]</together>
<span class="added-char"> </span>
<together>[
</template>
<template is="dom-if" if="{{isEndOfList(diffObj.value, index)}}">
]</together>
</template>
</template>
Resulting HTML:
I know the logic is correct as I used "[" and "]"to represent what the tags are doing visually. Such as:
[ - - - - ] [ - - - ] [ - - ! ]
Polymer: 1.0.3
More routing: 1.0.0
Having some issues with Polymer "more-routing". Those are -
1) Get this log on console -
[dom-bind::_annotatedComputationEffect]: compute method `urlFor` not defined
2) First level routing works (even though I get those error/warning messages). But second level routing (i mean nested routing) does not work. On "users" page pressing the name doesn't take me to "user-info" page. In fact the name does not appear as a link, it appears as a text. Here is my code -
My "routing.html"--
<link rel="import" href="../bower_components/more-routing/more-routing.html">
<more-routing-config driver="hash"></more-routing-config>
<more-route name="home" path="/"></more-route>
<more-route name="users" path="/users">
<more-route name="user-info" path="/:name"></more-route>
</more-route>
<more-route name="contact" path="/contact"></more-route>
My "index.html" ---
<more-route-selector>
<paper-menu class="list" on-iron-select="onMenuSelect">
<a route="home" href="{{urlFor('home')}}">
<iron-icon icon="home"></iron-icon>
<span>Home</span>
</a>
<a route="users" href="{{urlFor('users')}}">
<iron-icon icon="info"></iron-icon>
<span>Users</span>
</a>
<a route="contact" href="{{urlFor('contact')}}">
<iron-icon icon="mail"></iron-icon>
<span>Contact</span>
</a>
</paper-menu>
</more-route-selector>
<more-route-selector selectedParams="{{params}}">
<iron-pages>
<section route="home">
<paper-material elevation="1">
<bortini-home></bortini-home>
</paper-material>
</section>
<section route="users">
<paper-material elevation="1">
<h2 class="paper-font-display2">Users</h2>
<p>This is the users section</p>
Rob
</paper-material>
</section>
<section route="user-info">
<paper-material elevation="1">
<h2 class="paper-font-display2">
User:<span>{{params.name}}</span>
</h2>
<div>This is <span>{{params.name}}</span>'s section</div>
</paper-material>
</section>
<section route="contact">
<paper-material elevation="1">
<h2 class="paper-font-display2">Contact</h2>
<p>This is the contact section</p>
</paper-material>
</section>
</iron-pages>
</more-route-selector>
With 1.0 (perhaps earlier), Polymer stopped supporting expressions inside data-bindings (Migration Guide - Data binding). Thankfully, you can still call a function in a binding (called a "computed binding").
From what I can tell, the urlFor() method must be slightly too complex to work as a computed binding (the params object isn't a dependent property). I was able to make it work by wrapping urlFor() in a simpler function - one that works as a computed binding - something like this:
<more-routing-config driver="path"></more-routing-config>
<more-route name="users" path="/users">
<more-route name="user-info" path="/:name"></more-route>
</more-route>
<template is="dom-bind">
Rob
</template>
<script>
var template = document.querySelector('template');
template.makeUrl = function(route, name) {
return MoreRouting.urlFor(route, {name:name});
};
</script>
You can also pass variables in your computed binding, as long as they're dependent properties, like the item in a repeating template
<template is="dom-bind">
<template is="dom-repeat" items="{{users}}">
{{item.name}}
</template>
</template>
<script>
var template = document.querySelector('template');
template.makeUrl = function(route, user) {
return MoreRouting.urlFor(route, {name:user.name});
};
</script>
I have a problem with passing the category variable inside the <template> tag wrapped by the core-list.
I tried different binding approaches, but no luck. {{category}} corretcly appears outside the 2nd template tag.
<polymer-element name="library-list" attributes="category">
<template>
<style>
...
</style>
<service-library id="library" items="{{items}}"></service-library>
<core-list id="list" data="{{items}}" on-core-select="{{onClick}}">
<template>
<div class="item {{ {selected: selected} | tokenList }}" hidden?="{{category == type}}">
<div class="message">
<span class="title">{{title}}</span>
</div>
</div>
</template>
</core-list>
</template>
Maybe you want to try the injection approach.
<core-list data="{{data}}">
<template>
<div class="item {{ {selected: selected} | tokenList }}">
<span>{{foo}}-<b>{{category}}</b></span>
</div>
</template>
</core-list>
...
data.push({
foo: 999,
category:this.category,
...});
jsbin demo http://jsbin.com/mokok
I couldn't find a good solution, so I filtered the data instead that the core-list displays.