Reference Angular binding from javascript - angularjs

I'm looking for a (best-practice) way to iterate through a list of elements in the scope of an angular controller and generate a div with an element specific id and append a svg to the element specific div. I'm very new to Angular...and suspect that the following attempt fails because I misunderstand Angular bindings?
What is a better way to do the following:
<div id="top_level">
<div ng-repeat="item in items">
<div id={{item.id}}>
<script type="text/javascript">
var svg_img = build_svg(args);
document.getElementById({{item.id}}).appendChild(svg_img);
</script>
</div>
</div>
</div>
Thanks!

You should place your logic inside of your controller and conditionally render as much html as necessary rather than invoking a script tag inside of an ng-repeat..
<div ng-controller="YourCtrl">
<div id="top_level">
<div ng-repeat="item in items">
<div id={{item.id}}></div>
<div ng-bind-html="$scope.buildSvg(item)">
</div>
</div>
</div>
</div>
In your angular controller, you would then add a function to build out and return the svg for you to render.
app.controller('YourCtrl', ['$scope', function ($scope) {
$scope.buildSvg = function (item) {
// add logic here.
}
});

What does your function build_svg return?
We'd need a little more information about the kind of end-result you would like to get.
But yeah, it's not really good practice to have a script element within a ng-repeat directive.
I see two solutions here:
1- Build your SVG directly within the ng-repeat
<div id="top_level">
<div ng-repeat="item in items">
<div id={{item.id}}>
<svg height="{{item.svg.attrs.height}}" width="{{item.svg.attrs.width}}">
<circle cx="50" cy="50" r="40" stroke="black" stroke- width="3" fill="red" />
</svg>
</div>
</div>
</div>
Here is a plunker of this method:
http://plnkr.co/edit/g58BUPScjKHjRLAfx6ks?p=preview
2- Create a directive to generate your SVG with some additional parameters and flexibility.
<div id="top_level">
<div ng-repeat="item in items">
<div id={{item.id}}>
<my-svg attrs="item.svg.attrs"></my-svg>
</div>
</div>
</div>
The my-svg directive would generate a SVG element with the attrs parameters.

Related

How to create div and assign object to dataset dynamically using Angularjs

I have below div (class name 'sp') which I would like to dynamically create based on the sk from a dataset object.
div code
<div style="" class="swindow">
<div class="sp" style="">
<div class="svis" style="">
<div style="height:95%;width:95%;margin-top:0px;margin-left:5px;">
<chart dsn="dyndata" editable="false" labelled="true"></chart>
</div>
</div>
<div class="sdata" style="">
<div class="stext" style="">Average:78% </div>
</div>
</div>
While searching for similar examples, I came across ng-repeat in Angular js and I thought it might suit for this kind of objective.
But am very new to Angular js and not sure how to assign the data to my dyndata variable dynamically and create new div (class=sp) for each of the given id.
Here is the lookup object
[
{"id":20,"st":[{"label":"Audi","value":10},{"label":"BMW","value":70}]},
{"id":26,"st":[{"label":"Benz","value":40},{"label":"BMW","value":20}]},
{"id":12,"st":[{"label":"AUDI","value":60},{"label":"Tesla","value":70}]},
{"id":57,"st":[{"label":"MZ","value":30},{"label":"Honda","value":40}]}
]
When I input the id's as a set [12,26,57] - Three divs (each for #sp) should get created one for each of ids. In those, each div should have the dyndata assigned with the respective 'st' from above javascript object.
I could create div's in jquery using .append function to the container (#swindow) each time when I need. But am not sure how to assign sk as input to dyndata dataset for each div that gets created.
Could you please share how this can be achieved using Angular js ?
Here is the angular js code I used -
<script>
var app = angular.module('ExampleApp', ['ui.plot']);
app.controller('PlotCtrl', function ($scope) {
$scope.dyndata={};
});
</script>
I'm not exactly sure what you're trying to do but I think it should look something like this. Here is a plnkr..
Controller:
app.controller('PlotCtrl', function($scope) {
$scope.items = [
{"id":20,"st":[{"label":"Audi","value":10},{"label":"BMW","value":70}]},
{"id":26,"st":[{"label":"Benz","value":40},{"label":"BMW","value":20}]},
{"id":12,"st":[{"label":"AUDI","value":60},{"label":"Tesla","value":70}]},
{"id":57,"st":[{"label":"MZ","value":30},{"label":"Honda","value":40}]}
]
});
HTML:
<body ng-controller="PlotCtrl">
<div style="" class="swindow">
<div class="sp" style="" ng-repeat="item in items">
<div class="svis" style="">
<strong>{{item.id}}:</strong>
<div>-{{item.st[0].label}}</div>
<div>-{{item.st[1].label}}</div>
<div style="height:95%;width:95%;margin-top:0px;margin-left:5px;">
<chart dsn="dyndata" editable="false" labelled="true"></chart>
</div>
</div>
<div class="sdata" style="">
<div class="stext" style="">Average:78% </div>
<br>
</div>
</div>
</div>
</body>

Angular wrap transcluded elements separately?

I am fairly new with Angular. And although I've made a lot of progress there are still a couple of things I don't know.
Currently I am running into a transclusion 'problem'.
Basically what we want is to wrap every transcluded element/directive seperately with html that's controlled by the parent directive.
Example:
<my:directive>
<my:sub-directive>Child 1</my:sub-directive>
<my:sub-directive>Child 2</my:sub-directive>
<my:sub-directive>Child 3</my:sub-directive>
</my:directive>
Desired result (I've left the directive elements to make the example a bit more clear):
<my:directive>
<ul>
<li>
<div class="panel">
<div class="header">
// Some stuff that's controlled by my:directive comes here
</div>
<div class="content">
<my:sub-directive>Child 1</my:sub-directive>
</div>
</div>
</li>
<li>
<div class="panel">
<div class="header">
// Some stuff that's controlled by my:directive comes here
</div>
<div class="content">
<my:sub-directive>Child 2</my:sub-directive>
</div>
</div>
</li>
<li>
<div class="panel">
<div class="header">
// Some stuff that's controlled by my:directive comes here
</div>
<div class="content">
<my:sub-directive>Child 3</my:sub-directive>
</div>
</div>
</li>
</ul>
</my:directive>
Does anyone have a clue how to handle this? I know in my example I could introduce a panel directive, but note this is just an example of the same problem.
You can pass a fifth parameter to your directive's link function transclude and then do your manipulation in there, here's a quick example:
angular.directive('myDirective', function ($compile) {
return {
restrict:'EA',
transclude:true,
link: function (scope, elm, attrs,ctrl,transclude) {
transclude(scope,function(clone) {
//clone is an array of whatever is inside your main directive
clone.filter('mySubDirective').each(function(index, value){
//create your html and you might have to $compile it before:
elm.append(myHtml);
});
});
}
};
})

How can I call an angular controller function from my custom polymer web component?

I've seen this question and seen it answered but not in any way I can use or understand. The question is very specific and simple but somehow the answers are a bit over my head.
All I want to do is have a very simple menu work. when i menu item is clicked, I need it to of course use my angular controller function to handle it. I want all of that on the angular side. It actually does work when I simply use the elements directly without declaratively making my own.
So this works just fine and my ng-click is successfuly calling my acceptedSelect() in my controller:
<core-menu>
<div ng-repeat="order in acceptedOrders" ng-click="acceptedSelect(order)">
<paper-item class="my-paper-item" >
<div class="order-list-item">
<div class="order-number">{{order.Order}}</div>
<div class="order-date"> {{order.Date}} </div>
<div style="clear: both"></div>
<div class="order-address">
{{order.Property}}
</div>
</div>
</paper-item>
</div>
</core-menu>
But i do the same thing by wrapping the paper element in a polymer-element, it doesn't work. So this will not work:
<polymer-element name="my-app" attributes="refresh">
<template>
<style>
...
</style>
<core-menu>
<div ng-repeat="order in acceptedOrders" ng-click="acceptedSelect(order)">
<paper-item class="my-paper-item" >
<div class="order-list-item">
<div class="order-number">{{order.Order}}</div>
<div class="order-date"> {{order.Date}} </div>
<div style="clear: both"></div>
<div class="order-address">
{{order.Property}}
</div>
</div>
</paper-item>
</div>
</core-menu>
</template>
<script>
Polymer('my-app', {
});
<my-app></my-app>
I'm just not sure what I can do to make this work. Any help is greatly appreciated.

change angular ui-view inside ng-repeat

I am using multiple named ui-views in a single controller. Everything is working as spected when name the ui-view in the html file with this code:
<div class="box">
<div ui-view="selector"></div>
<div ui-view="widget1"></div>
<div ui-view="widget2"></div>
<div ui-view="widget3"></div>
<div ui-view="widget4"></div>
</div>
But when I want to load dynamically some of those views with a ng-repeat it does not update the information.
<div class="widgets">
<div class="widget-container" ng-repeat="widget in widgets">
<div ui-view="{{widget}}"></div>
</div>
</div>
How could I load ui-views from my ng-repeat?
This hadn't been answered so i decided to go ahead and show how to do it. Unfortunately for some reason the attempt in the question didn't work but what you can do is link to a function between curly brackets and return the string of the view you want. For instance the controller would look like this:
$scope.groups = ['main','cases', 'models'];
$scope.pickView = function(index){
return $scope.groups[index];
};

AngularJS: data-ng-model & data-ng-hide/show

My index.html page is like as follows:
<div id="sidepanel" data-ng-controller="ListCtrl">
<li data-ng-repeat="record in records">
{{record.id}}
<input type="checkbox" data-ng-model="addwidget">
</li>
</div>
<div id="main">
<div data-ng-view></div>
</div>
for this data-ng-view i have another page recordlist.html in that i have following code:
<div data-ng-controller="ListCtrl">
<ul class="design">
<li data-ng-repeat="record in records">
<div data-ng-switch data-on="record.category">
<div data-ng-switch-when="reporting1">
<div id="{{record.id}}" data-ng-show="addwidget">{{record.description}}</div>
</div>
<div data-ng-switch-when="reporting2">
<div id="{{record.id}}" data-ng-hide="addwidget">{{record.description}}</div>
</div>
</li>
</ul>
</div>
My question is i want to show the first div when i check the checkbox & when i uncheck it i want to show the second div.When both of the data-ng-model & data-ng-hide/show are on the same page then it works fine but in my case it present on two different pages.
Is it correct ? How can i implement this. Need Help.Thanks.
The problem is that you are setting addwidget in the first controller, but is trying to use it in the second. Controllers are not singletons.
So, in this situation:
<div id="sidepanel" data-ng-controller="ListCtrl">
...
</div>
<div id="main">
<div data-ng-view>
<div data-ng-controller="ListCtrl">
</div>
</div>
</div>
You got two separated controllers and scopes. And you are setting addwidget in the first trying to read in the second.
You can either bind it to the root scope $root.addwidget or use a service share to the states.
As you have many records, binding directly to root is a problem, as all of them are going to share the same state. So you gonna need an object in the rootScope and bind the option by id $root.addwidget[record.id]. Made a pretty simplified modification here.

Resources