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

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.

Related

Angular Bootstrap Collapsible Column

I was looking for a angular/bootstrap non javascript solution to have a collapsible bootstrap column..
Here's what I came up with when I couldn't find another solution online.
It was important to me to not use jquery (don't want to clutter up my controller with UI stuff)
It's not rocket science, but I spent a while looking for a bootstrap solution and came up dry.
<button ng-click="showAddDiv = !showAddDiv">Show</button>
<div class="container-fluid">
<div class="row">
<div class="material-color-primary-1 col-xs-12" ng-class="{true:'col-lg-8', false:'col-lg-12'}[showAddDiv]" ng-init="showAddDiv = false">
</div>
<div class="material-color-secondary-1" ng-class="{true:'col-xs-12 col-lg-4', false:'hidden'}[showAddDiv]">
'add div'
</div>
</div>
</div>

Reference Angular binding from javascript

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.

angular wizard ng-view and angularui modal

I am building a wizard in angular using the angular-ui bootstrap modal component.
In my main page, I am already using ng-views for navigation.
The goal is to create a modal wizard on one of these pages. As far as I can see,
nested ng-views are not supported. If possible, I would like to keep each step of
the wizard as an external resource.
A terrible way to accomplish this at the moment is something to this effect:
<div id="wizardModal" class="modal hide">
<div class="modal-header">
<div ng-show="isCurrentStep(1)">
<p>Step1 header</p>
</div>
<div ng-show="isCurrentStep(2)">
<p>Step2 header</p>
</div>
<div ng-show="isCurrentStep(3)">
<p>Step3 header</p>
</div>
</div>
<div class="modal-body">
<div ng-show="isCurrentStep(1)">
<p>Step1 body</p>
</div>
<div ng-show="isCurrentStep(2)">
<p>Step2 body</p>
</div>
<div ng-show="isCurrentStep(3)">
<p>Step3 body</p>
</div>
</div>
<div class="modal-footer">
<div ng-show="isCurrentStep(1)">
<p>Step1 footer</p>
</div>
<div ng-show="isCurrentStep(2)">
<p>Step2 footer</p>
</div>
<div ng-show="isCurrentStep(3)">
<p>Step3 footer</p>
</div>
</div>
</div>
Obviously, the above is unacceptable and will create maintenance nightmares.
Is there a clean approach to accomplishing the same effect?
Using ng-include worked like a charm, thanks.
You can find a tutorial about creating a wizard-style app using ng-view and ngRouter here.
I believe this approach is much better since you can have individual controllers per step that inherit the scope from the host form thus keeping all the data but separating the logic.

AngularJS using ng-switch without wrapper div

I would like to use ng-switch because I do not want the other elements that I do not want to show to be part of the DOM. That is why i did not use ng-hide/ng-show. In the example below, I would like to only have the span tag be in the DOM without the div wrappers from the ng-switch. What is the best way to accomplish this?
<div ng-switch on="user">
<div ng-switch-when="true">
<span>One</span>
</div>
<div ng-switch-when="false">
<span>Two</span>
</div>
</div>
You can use the ng-switch directive as a custom element and not specify the div in the first place. For example:
<ng-switch on="user">
<span ng-switch-when="true">One</span>
<span ng-switch-default>Two</span>
</ng-switch>
Here is a plunker to play around with: http://plnkr.co/edit/zni6raUWOguhQh9jDiY3
the solution provided by #ChrisAuer this still creates a wrapping element.
AFAIK you'd have to use a custome directive. You may want to use angular-ui if
<div ui-if="user">
<span>One</span>
</div>
<div ui-if="!user">
<span>Two</span>
</div>
Probably, in your case, you'd be fine using ng-show or ng-hide which only hide(display:none) the element - they don't remove it form the DOM.
<div ng-show="user"> <!-- same as ng-hide="!user" -->
<span>One</span>
</div>
<div ng-hide="user"> <!-- same as ng-show="!user" -->
<span>Two</span>
</div>
I would say use ng-if, like this:
<div>
<div ng-if="user==true">
<span>One</span>
</div>
<div ng-if="user==false">
<span>Two</span>
</div>
</div>
you can use <span> to prevent your html layout changing
because <span> is not like <div>, it won't take up any space.
<span ng-switch="user">
<span ng-switch-when="true">One</span>
<span ng-switch-default>Two</span>
</span>

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