Allowing multiple directives to transclude in a recursive template - angularjs

I am currently receiving a tree of managers and their subordinates from the back end. I'm using a recursive template to display this.
<script type="text/ng-template" id="managerTmp">
<div class="accordion">
{{user.firstName}} {{user.lastName}}
<ul class="list-group" ng-if="user.subordinates" >
<li class="list-group-item" ng-if="user.subordinates" ng-repeat="user in user.subordinates" ng-include="'managerTmp'">
</li>
</ul>
</div>
</script>
<div class="col-lg-12" ng-show="section === 5">
<uib-accordion close-others="oneAtATime" ng-show="portal.acManagers && !spinning">
<ul class="list-group" id="1q2w3e">
<li class="list-group-item" ng-repeat="user in portal.acManagers" ng-include="'managerTmp'" ></li>
</ul>
</uib-accordion>
</div>
This all works fine and I get a ul/li of the tree. However, whenever I try changing the ul/li to the angularUI accordion (uib-accordion & uib-accordion-group) i get an error saying
Error: [$compile:multidir] Multiple directives [ngInclude, uibAccordionGroup (module: ui.bootstrap.accordion)] asking for transclusion on: <uib-accordion-group class="list-group-item" ng-if="user.subordinates" ng-repeat="user in user.subordinates" ng-include="'managerTmp'" id="azqx">
I don't fully understand the issue or why angularjs does not allow this? Any help would be greatly appreciated.

Related

Number of watchers adding up with ng-repeat

The below code renders tabs, sections under each tab and the content of the section. When navigating from one section to another, I notice the number of watchers are increasing (or) adding up each time.
Can any one tell what could be the reason for this. Appreciate any pointers
<ul class="nav nav-tabs">
<li ng-repeat="tab in tabList track by tab.tabId" id="{{tab.attribute}}"
ng-class="{active:selectedTab.attribute === '{{tab.attribute}}'}">
<a showtab="" href="#{{tab.attribute}}" ng-click="setSelectedTab(tab)">{{tab.displayLabel}}</a>
</li>
</ul>
<div class="tab-pane">
<div class="" ng-if="selectedTab.sectionList.length > 0">
<ul class="nav nav-pills pills-section">
<li ng-repeat="section in selectedTab.sectionList track by section.sectionId" id="{{section.attribute}}" ng-class="{active:selectedSection.attribute === '{{section.attribute}}'}">
<a showtab="" href="#{{section.attribute}}" ng-click="setSelectedSection(section)">{{section.displayLabel}}</a>
</li>
</ul>
<!-- Content of the section rendered with ng-repeat -->
<div ng-include="sectionContent"/>
</div>
</div>
The section content has the below mark up
<table>
<tbody>
<tr ng-repeat="field in selectedSection.fields track by field.fieldId">
</tr>
</tbody>
</table>
I have had similar problems before, nesting ng-repeats is never a good idea, but we are forced from time to time to do it. This is your solution to have performance benefits.
http://kamilkp.github.io/angular-vs-repeat/

ng-repeat list item is not rendering inside the anchor

So heres what the html looks like in the text editor...
<div ng-repeat="x in Result">
<a ng-href="https://domain.com/{{x.short_url}}">
<li class="viewer" id="{{x.user_id}}" style="background-image: url(https://domain.com/{{x.user_id}})">
</a>
</div>
But when its rendered in the browser it looks like this...
<a ng-href="https://domain.com/ucmzda" href="https://domain.com/ucmzda"></a>
<li class="viewer" id="b5599b09bcb3467ba3ade4e5b30721a4" style="background-image: url(https://domain.com/image/user/b5599b09bcb3467ba3ade4e5b30721a4)">
I cant figure out why the list item is not rendering inside the anchor?
<div ng-repeat="x in Result">
<a ng-href="https://domain.com/{{x.short_url}}">
<li class="viewer" id="{{x.user_id}}" style="background-image: url(https://domain.com/{{x.user_id}})"><li>
</a>
</div>
refer:
ng-repeat inserting empty anchor tags
In your case li is not closed:
It is not a good practies to use li inside a tag:
use like this
<ul ng-repeat="x in Result">
<li class="viewer" id="{{x.user_id}}" style="background-image: url(https://domain.com/{{x.user_id}})"><a ng-href="https://domain.com/{{x.short_url}}">
</a>
</li>
</ul>
Have you by any chance configured your $locationProvider to html5Mode? If yes this would cause your problems. You could force it to always go to the url by adding target="_self" to your tag. Give it a shot.**
use HTML5 so adding the target="_self" it will work

angular-ui-tree click doesn't work

I downloaded the angular-ui-tree package and installed it in a webserver. I can bring up the example pages fine in my browser, but all the click actions on the buttons (to collapse/expand the tree, add node etc) do not work. I don't get any errors in firebug.
If I point my browser at the public page for the tree component ( https://jimliu.github.io/angular-ui-tree/index.html) it does work.
I did some debugging and found that the problem is when ng-repeat is called for a ui-tree-node element, an ng-click action does not work.
In the code below, the test() function is in my controller and it gets executed if I remove the ui-tree-node or ng-repeat tags.
<li ui-tree-node ng-repeat="node in mydata" >
<a ng-click="test()" >{{node.title}} </a>
</li>
Is this a bug in angular tree component?
Is there some way I can fix this in my environment?
The fix was to add the data-nodrag tag in the top level ui-tree-nodes element.
(adding data-nodrag in the li element also works).
You can use both:
click with toggle(this)
drag
together, just make sure that the element to expand/collapse ist not within the ui-tree-handle
<script type="text/ng-template" id="tree_renderer.html">
<div ng-class="{collapsed: collapsed}">
<div class="ctx_node"
ui-on-drop="onDrop($event, $data, ctx,node); active=false">
<span class="expanded"
ng-click="toggle(this)"
ng-class="{'collapsed': collapsed,'expanded': !collapsed}">
</span>
<span ui-tree-handle>{{node.title}}</span>
</div>
</div>
<ol ui-tree-nodes="" ng-model="node.nodes">
<li ng-repeat="node in node.nodes"
ui-tree-node ng-include="'tree_renderer.html'">
</li>
</ol>
</script>
<div ui-tree data-drag-enabled>
<ol ui-tree-nodes="" ng-model="node.nodes" id="tree-root">
<li ng-repeat="node in node.nodes"
ui-tree-node ng-include="'tree_renderer.html'"></li>
</ol>
</div>

How to make AngularUI sortable connect lists in different divs?

I'm trying to get AngularUI sortable connect two lists located in separate divs.
Can someone please explain what the issue is and why one method works and the other doesn't ? and what I need to do to fix it ?
I did get the lists connected if the divs are both siblings of the element defining the sortable:
<div ui-sortable="sortableOptions" ng-repeat="list in modelData" ng-model="list" class="sort">
<div id="item-list" ng-repeat="item in list">{{item}}</div>
</div>
jsfiddle: http://jsfiddle.net/GaryM/PHvVS/
This is the method I need to work:
<div class="sortSrc" style="display:inline;">
<ol ui-sortable="srcSortableOptions" ng-model="srcData">
<li ng-repeat="item in srcData">{{item}}</li>
</ol>
</div>
<div class="sortTgt" style="display:inline;">
<ol ui-sortable="tgtSortableOptions" ng-model="tgtData">
<li ng-repeat="item in tgtData">{{item}}</li>
</ol>
</div>
jsfiddle: http://jsfiddle.net/GaryM/2AnLU/
Help is appreciated
remove parent divs for ol's. Here works just fine
Please see the refer how they do in official github of ui-sortable
<div>
<ol ui-sortable="srcSortableOptions" ng-model="srcData" class="sortSrc" style="display:inline;">
<li ng-repeat="item in srcData">{{item}}</li>
</ol>
<ol ui-sortable="tgtSortableOptions" ng-model="tgtData" class="sortTgt" style="display:inline;">
<li ng-repeat="item in tgtData">{{item}}</li>
</ol>
</div>

Adding ng-click event with jQuery

Being new to Angularjs, I need a bit of help with this issue. I am attempting to add ng-click="getGallery(57)" to a modal tab. Adding via jQuery is not the issue, however I realize when I do this, Angular is not compiling the newly added ng-click. I have a simple controller
function imageGalleryCtrl ($scope, $http) {
//get gallery info on click
$scope.getGallery = function(id)
{
$http.post('/beta/images/get_images',{'id': id}).success(function(data)
{
$scope.images = data.thisGal_images;
$scope.images.galID = id;
});
};
}
I add the ng-click to the element with jQuery
//Edit image tab to use angularjs
$('#image_edit a').attr('ng-click','getGallery(' + settings.id + ')');
How do I force Angular to compile this newly added ng-click?
Thanks!
HTML Modal:
This is the modal that is called when the gallery name is clicked.
<div class="modal fade hide modal-creator" id="imageUploader" tabindex="-1" data-focus-on="input:first">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"></button>
<h3>Create New Gallery</h3>
</div>
<div class="modal-body">
<ul id="myTab" class="nav nav-tabs">
<li id="image_home" class="">
Home
</li>
<li id="image_upload" class="">
Upload Image Gallery
</li>
<li id="image_edit" class="">
Edit Image Gallery
</li>
</ul>
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade in" id="home">
<?php include('create.php'); ?>
</div>
<div class="tab-pane fade" id="upload">
<?php include('upload.php'); ?>
</div>
<div class="tab-pane fade" id="edit">
<div class="span9">
<ul id="imageSort" class="gallery-container">
<li ng-repeat="image in images">
<img ng-src="http://images.onlinealbumproofing.com/imageGallery/{{image.galleryID}}/{{image.imageName}}" alt="">
{{image.orgName}}
</li>
</ul>
</div><!-- /span9 -->
</div><!-- /row -->
</div>
</div>
</div><!-- /modal-body -->
<div class="modal-footer">
Close
Next
</div>
</div>
Update
So really attempting to do this the Angular way, and after some studies here is where I am at.
The controller is the same as above and I have updated the tabs on the modal as follows.
<div class="modal-body">
<ul id="myTab" class="nav nav-tabs">
<li id="image_home" class="">
Home
</li>
<li id="image_upload" class="">
Upload Image Gallery
</li>
<li id="image_edit" class="">
<a ng-click="getGallery(57)" href="#edit" data-toggle="tab">Edit Image Gallery</a>
</li>
</ul>
If I hard code the ng-click as above, the tab updates as expected. What I am trying to make happen, is when the modal is called, (#image_edit a) gets a defined ng-click="getGallery(id). I need to tell Angular to look at the ng-click again for the id.
Although I too think that you should try and find another approach, the answer to your question
How do I force Angular to compile this newly added ng-click?
is
// remove and reinsert the element to force angular
// to forget about the current element
$('#button1').replaceWith($('#button1'));
// change ng-click
$('#button1').attr('ng-click','exec2()');
// compile the element
$compile($('#button1'))($scope);
See this working example: http://plnkr.co/edit/SgvQzaY0TyFHD1Mf0c3F?p=preview
Basically what I'm getting at is you want to probably make this happen:
<ul id="imageSort" class="gallery-container">
<li ng-repeat="image in images">
<img
ng-src="http://images.onlinealbumproofing.com/imageGallery/{{image.galleryID}}/{{image.imageName}}"
alt=""
ng-click="getGallery(image.galleryID)"
>
{{image.orgName}}
</li>
</ul>
The problem is I'm unsure of the relationship between the settings.id and the galleryID for a particular image. If you can set up this relationship in the data so it just automatically binds you're in better shape.

Resources