Element transclusion - angularjs

Is there something like angularjs directive's transclude attribute in polymer? Something what allows me to include some elements to a specific place in template?
I would like to achieve something like following:
<my-header title="My title">
<my-header-item name="Item 1"></my-header-item>
<my-header-item name="Item 2"></my-header-item>
</my-header>
which might be expressed:
<h1>My title</h1> <!-- "My title" given by my-header's title attribute -->
<ul>
<li>Item 1 <!-- given by my-header-item -->
<li>Item 2
</ul>
I am not sure if this is a task for polymer or if this is a typical way to use polymer. I am asking, because I started to like polymer and I would like to keep idiomatic thinking.

In Shadow DOM land, this is called distribution. To distribute light DOM nodes into the shadow dom, you use <content> insertion points.
http://www.polymer-project.org/platform/shadow-dom.html#shadow-dom-subtrees
It's quite literally a way to render nodes from light dom into placeholders in the shadow dom.
If you want to do tricky things with the my-header/my-header-item title/name attributes, you can do something like this:
<polymer-element name="my-header">
<template>
<ul>
<template repeat="{{item in items}}">
<li>{{item.name}}</li>
</template>
</ul>
<content id="c" select="my-header-item"></content>
</template>
<script>
Polymer('my-header', {
domReady: function() {
this.items = [].slice.call(this.$.c.getDistributedNodes());
}
});
</script>
</polymer-element>
Demo: http://jsbin.com/hupuwoma/1/edit
I have a more full-fledged tabs demo does this setup over on https://github.com/ebidel/polymer-experiments/blob/master/polymer-and-angular/together/elements/wc-tabs.html.

While admittedly I'm also new to polymer - I think I can answer this.
You should be able to substitute the value of an attribute into the template using the double-mustache syntax e.g.
<h1>{{title}}</h1>
See http://www.polymer-project.org/docs/start/creatingelements.html#publishing
In addition to this you can also substitute the content of a tag. For example if instead of using the "name" attribute in your my-header-item tag you instead had something like this...
<my-header-item>Item 1</my-header-item>
then you could substitute "Item 1" like this:
<li><content></content></li>
See http://www.polymer-project.org/platform/shadow-dom.html for this usage

Related

Uib-alert css style is not applying

<uib-alert ng-repeat= "alert in ConfigurationAlerts" close="closeAlert($index)"> {{alert.msg}} </uib-alert>
var eWiggle = angular.module('eWiggleApp',['ui.router', 'ngAnimate', 'ui.bootstrap','blockUI','ngCookies']);
As of version 2.0 the uib-alert directive was changed to an attribute rather than an element, meaning you need to attach it to a div. You haven't specified a class either, which is what determines the colour scheme of the alert. Your example should look like this:
<div uib-alert ng-class="'alert-success'" ng-repeat="alert in ConfigurationAlerts" close="closeAlert($index)"> {{alert.msg}} </div>
The documentation has an example which is worth looking at.

AngularJS Databinding Expression not working inside tooltip plugin template

*EDIT: Mike pointed out an issue with a type. the real problem i want to solve includes a template with cluetip. See this revised plnkr:
http://plnkr.co/edit/UGH3cV3z9MrqA4eyPjLc?p=preview
I'm sure this is related to the digest loop and the jquery plugin cluetip, but I don't know what steps I need to make the data binding work inside template. I've put the simple example in plnkr to show what I mean.
http://plnkr.co/edit/YW7AsTEuJh2ixqSUJpld?p=preview
The code in question is this:
head>
Cluetip - AngularJS
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<link rel="stylesheet" href="jquery.cluetip.css" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="jquery.cluetip.js"></script>
<script type="application/javascript">
$(function() {
$('a.title').cluetip({
splitTitle: '|'
});
});
</script>
</head>
<body ng-app>
<input ng-model="somedata" placeholder="Some Data">
<br/>{{ somedata }}
<hr/>
<br/>
<a class="title" href="#" title="This is the title| someData: {{ someData }} .|In this case, the delimiter is a pipe">In Line Text</a>
</body>
Couple of issues going on here...
First, you don't have a controller managing this, so the scope that is created by the tag is not visible to the somedata reference in your tooltip title. To correct this, you need to reference a controller:
<body ng-controller="MainCtrl">
and setup the somedata scope value in that controller:
$scope.somedata = 'somedata';
Second, you have a small typo in the title reference (you have a capital "D" in somedata):
title="This is the title| someData: {{ someData }} .|In this case, the delimiter is a pipe"
should be
title="This is the title| someData: {{ somedata }} .|In this case, the delimiter is a pipe"
And, finally, it appears the jQuery cluetip code is creating a copy of the value, so it's not dynamic. In reality, it's probably setting up the DOM objects once at initialization and never referencing the "title" attribute again -- just hiding and showing the created content. Therefore, changing the value of the "title" attribute appears to be ignored.
I forked a Plnkr here with the above changes (including referencing the script.js file where a controller now resides): http://plnkr.co/edit/hzW6AtJBj4zPPM405n5Y?p=preview
Notice it all works; however, the cluetip doesn't change dynamically as the somedata value changes. I made a duplicate of the anchor below the first one in the Plnkr, but changed the class so cluetip wouldn't attach and it's a standard tooltip. You'll see that this tooltip does update dynamically -- using the same input box and somedata.
Beyond the above, I think you'll have to find a way to either trigger and update to the cluetip initialization or use a different widget. As an aside to all this, you'd probably be better served exploring a native angular directive for this so you don't run into this type of issue. Maybe something like http://angular-ui.github.io/bootstrap/#/tooltip

How to: Angular Tree?

Hi all you experts out there.
My testing area: http://plnkr.co/edit/ddJT1e4a8L5NTSIVNTk7
I am trying to visualize hierarchical data in a tree-form with Angular, even though i'm using some samples to aid me in my quest (like http://jsfiddle.net/alalonde/NZum5/ and http://jsfiddle.net/brendanowen/uXbn6/8/) i fail.
As soon as i place the recursive element ng-include inside the ng-repeat in side the template it self, the memory usage of its browser-window goes through the roof and effectively hangs the browser. But the available tree-sample i could find are doing just that.
What am i missing?
You need to use the same variable name in the template. The current node is called node in the controller then child in the template.
This cause the template to render the same node over again.
It works fine if you use the same variable name :
<li ng-repeat="node in node.children" ng-include="'node.html'"></li>
See it in action here : http://plnkr.co/edit/mjfdSEDcMK8kGCRjS6V6?p=preview
If anyone here wants to avoid having the extra ng-repeat outside of the template (where it kind of includes stuff from the template anyway), here's a fiddle showing how to do it:
http://jsbin.com/hokupe/1/edit
Also here's a blog post and a 10-15 minutes video on how it works:
http://gurustop.net/blog/2014/07/15/angularjs-using-templates-ng-include-create-infinite-tree/
Sample Code:
<script type="text/ng-template" id="treeLevel.html">
<ul>
<li ng-repeat="item in items">
<input type="checkbox"
name="itemSelection"
ng-model="item._Selected" />
{{item.text}}
<div ng-include=" 'treeLevel.html'"
onload="items = item.children">
</div>
</li>
</ul>
</script>
<div ng-include=" 'treeLevel.html' "
onload="items = sourceItems">
</div>

Analog of ngTransclude in Angular.Dart

I'm trying to figure out how to make a component render its children.
So I can compile:
<my-component>
<div id="child"></div>
</my-component>
into something like this:
<div id="parent">
<!-- some component stuff -->
<div id="child"></div>
</div>
Is there something like ngTransclude in Angular.Dart?
AngularDart uses Shadow DOM in place of ngTransclude. This is one of the ways we are pushing Angular into the browser with emerging web standards.
Adding a <content> tag instead your component's template will cause the child element to be placed there.
e.g. in your example <my-component>'s template might look like:
<div id="parent">
<!-- some component stuff -->
<content></content>
</div>
For even more awesomeness, you can use Shadow DOM's content selectors as well to control which child elements are displayed.

Backbone: mixing html and javascript in template

In this "hello world" example of a Backbone app http://arturadib.com/hello-backbonejs/docs/5.html, the author renders a template inline like this
render: function(){
$(this.el).html('<span style="color:black;">'+this.model.get('part1')+' '+this.model.get('part2')+'</span> <span class="swap" style="font-family:sans-serif; color:blue; cursor:pointer;">[swap]</span> <span class="delete" style="cursor:pointer; color:red; font-family:sans-serif;">[delete]</span>');
return this; // for chainable calls, like .render().el
},
which, although functional, is a bit of an unmanageable html concatenation.
I've seen authors of other Backbone apps set a template in the view using underscore's template function
template: _.template($('#my-template').html()),
and then render it instead of the html
$(this.el).html(this.template(this.model.toJSON()));
I wanted to try this technique with the hello world app, but when I created the template file, I ran into the problem that it wasn't strictly html. As you'll notice it calls functions
this.model.get('part2')
and the template that I was using as a model (from another author's app, see below) just included html.
Question, What would I need to do to include javascript and html in the same template file so I can make a call to the model?
<script type="text/template" id="item-template">
<div class="company">
<div class="display">
<span class="company-text"></span>
<span class="company-mood">
<span class="mood"></span>
</span>
<span class="company-destroy"></span>
</div>
<div class="edit">
<input class="company-input" type="text" value="" />
</div>
</div>
</script>
See this link Underscore Template for details on what you want to accomplish.
But in general, if you just wanted to interpolate your this.model.get('someAttr'); all you'd need to do is include this in your template.
// Since you call it like this:
$(this.el).html(this.template(this.model.toJSON()));
// Just include this
<div>
<%= someAttr %>
</div>
You're basically passing in the model attributes object and the underscore template just interpolates the properties of that object. You can pass in anything you want although what you do with the render call is what's probably most common.

Resources