Rendering a variable number of ngGrids after page load - angularjs

I have an angular app. I load a spreadsheet into it, do some javascript, and then I want to render a variable number of tabs each with an ngGrid depending on whats in the spreadsheet I load into the page. Therefore I have to render the html with the angular markup after app initialization.
I tried putting the part of the page with the tabbed ngGrids in a nested controller and not doing app.controller('SubController', SubController); until after the spreadsheet is parsed. However, the controller is getting initialized at page load.
My initialization code looks like:
var app = angular.module('app', ['ngGrid', 'percentage', 'ui.bootstrap', 'angularFileUpload', 'vr.directives.slider']);
What do I do to make the nested controller not initialize at page load time?

Obvious in hindsight, was just to use a ngRepeat directive.
<div id="x-{{ $index }}" class="col-sm-12" data-ng-repeat="Grid in Grids" style="display: none">
<div id="divGrid-{{ $index }}" data-ng-grid="Grid" class="gridStyle"></div>
</div>

Related

Open multiple instances of same partial view and controller in angularJS

I am developing single page application using partial views and angularJS.
I am having a scenario where I have to open same partial view multiple times with different data.
I tried to make controller name dynamic by adding app.directive and changing controller name both in js and html and then calls Angular-Complies method, but the issue is that it changes it for all previous tabs opened.
Then I tried to make multiple js files and changing controller name in partial view with Jquery but still does not helps. Here is my code.
HTML:
<div ng-app="myApp">
<!-- this is in view1.html -->
<div ng-controller="DashboardDesignerController">
<div ng-repeat="widget in workspace.widgets">stuff here
</div>
</div>
<!-- this is in view1.html -->
<div ng-controller="DashboardDesignerController">
<div ng-repeat="widget in workspace.widgets">stuff here
</div>
</div>
//Angular controller is in separate JS file.
app.controller("DashboardDesignerController" , function ($scope, $http,
$rootScope, $compile, $injector, $timeout) {
}
I expect to behave every tab separately according to its data but currently when I go to first opened tab, it's scope changed with the last opened tab.
Is there built in way of angularJS to doing it, Or some good approach will also appreciated.
Actually the issue was, I was calling chart drill down method in core JavaScript which was replacing $scope with last opened.
Resolved the issue by getting scope with JQuery
var scope= angular.element($('.k-state-active').find('.tempDiv')[0]).scope();
and called angular function with this scope variable.

Is there a way to get transform with template to html?

I am using bootbox, I need display product information in it. The product information is returned as json with rest call. I am thinking using a template, and transform from the json to html. I need ng-repeat etc, in the template. The idea way is I can call template and get a html result.
But it seems angularjs $compile need bind to element to render. any idea?
I think you can use ng-include:
var app = angular.module('myApp', []);
app.controller('productCtrl', function($scope) {
$scope.productInfos = [];
});
Use ng-include (You have to the adjust the path depending the location of your template)
<div ng-app="myApp" ng-controller="productCtrl">
<div ng-include="'product-information.html'"></div>
</div>
You can do ng-repeat in product-information.html:
<div ng-repeat= "info in productInfos"> {{ info.prop1 }}</div>

Angularjs use same ng-app multiple times on page

I'm dealing with a content management system that needs to "inject" a reusable component into a page.
I want to inject the following component (html and javascript).
<script type="text/javascript">
if(typeof angular == 'undefined') {
document.write(unescape("%3Cscript type='text/javascript' src='/resources/scripts/lib/angular.min.js'%3E%3C/script%3E"));
document.write(unescape("%3Cscript type='text/javascript' src='/resources/scripts/pricing/app.js'%3E%3C/script%3E")); }
}
</script>
<div ng-app="pricing" ng-controller="PriceController as pc" ng-init="pc.getPrices('myprod', 'PER')">
Some text {{ pc.prices.msg["startdat tarief"] | jsDate }} .
More text {{ pc.prices.msg["einddat product"] | jsDate }}.
</div>
The component must be able to be injected multiple times on the page.
The problem is that the controller works fine, but only for the first injection.
This probably has something to do with that I am using the same app multiple times.
I am fairly new to angular.
How can I inject the same component multiple times?
Note that I am not able to init the app on a higher level. Because this would require the content manager to edit all pages, we juist want to inject a HTML component with javascript (i.e. the code snippet).
If you are able to add a unique ID to the module div you can manually bootstrap your angular app as follows:
function bootstrapAngular(id) {
angular.bootstrap(document.getElementById('module-' + id), ['app']);
}
angular.module('app', []).controller('sample', function ($scope) {
$scope.foo = 'bar';
});
bootstrapAngular(1);
bootstrapAngular(2);
bootstrapAngular(3);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div id="module-1">
<div ng-controller="sample">
{{ foo }}
</div>
</div>
<div id="module-2">
<div ng-controller="sample">
{{ foo }}
</div>
</div>
<div id="module-3">
<div ng-controller="sample">
{{ foo }}
</div>
</div>
You cannot have multiple ng-App directives on a single page. From the Angular.js documentation:
Only one AngularJS application can be auto-bootstrapped per HTML document. The first ngApp found in the document will be used to define the root element to auto-bootstrap as an application. To run multiple applications in an HTML document you must manually bootstrap them using angular.bootstrap instead. AngularJS applications cannot be nested within each other.
If placing ng-App higher in the tree isn't an option, you will have to re-write the components so that each component gets a unique angular.module() and when the component is injected, it will need to fire angular.bootstrap().

Angular looping through items in controller

I have a unique scenario where I would like to be able to do angular ng-repeat type logic in the controller. I am using a slidebar on mobile sized screens, which requires the div that makes up the navigation to sit outside the containing div of the website.
This logic is inside of my index.ejs express file:
<body>
<div ng-view></div>
<div class="sb-slidebar sb-left"></div>
</body>
My standard desktop size sidebar does typical ng-repeat logic:
<li ng-repeat="items in service">{{item.title}}</li>
Since the slidebar logic is in the core index.ejs express file on the server side, I don't have access to the angular view logic. My solution at the moment is to do logic in the controller based on the url:
$scope.$on('$viewContentLoaded', function () {
var index = window.location.pathname.split('/')[1];
if(index == 'services'){
$(".sb-left ul").html("<li>service categories<li>");
}
}
This approach works; however, I'd the inner html to be updated dynamically, similar to the template tag instead of being hardcoded like it is now.

Using a directive to add content to areas outside ng-view

I'm attempting to port an existing Ruby on Rails frontend to Angular. So far I've managed to get a single page app in place that switches out the content of ng-view depending on your angular route. This is great, however - in my RoR layout I have several defined areas where content can be placed, all of these are contextual to the main view. For example: Sidebar and Heading.
In RoR I can do the following from within an action view to set sidebar content.
<p>Product page content</p>
<% content_for :sidebar do %>
<% render :partial => 'product_sidebar' %>
<% end %>
I am struggling to determine the best method to achieve this in Angular. I've got it working with two methods:
SidebarUrl added to route definitions, route change event updates a scope variable which an ng-include directive uses in the layout.
Custom directive that is served with the template loaded into ng-view, e.g.
<p>Main content for the view</p>
<sidebar>
Content for sidebar
</sidebar>
The directive basically copies its innerHTML to the sidebar element in the main layout and then removes itself. It could be written to place the content into a target element defined by an attribute to make it more generic and reusable.
This way is more natural to me as the result is closest to the Ruby on Rails way but I'm not sure if its a decent solution or something that I will run into problems with later on (I'm very new to Angular).
Any thoughts or suggestions welcome.
UPDATE 18/06
I've found the Angular UI Router project: https://github.com/angular-ui/ui-router which seems to cover my requirements in an official way. Leaning towards that as a solution at the moment.
Try this (not tested).
You can have another element outside of your <div ng-view> element: say, <div id="sidebar" ng-controller="sidebarContr">. Since you can inject as many dependencies as you like in to sidebarContr, you can use $location as one of its parameters and check the location there and add properties to $scope to make the div display what you need.
For example:
in your controllers JS:
(angular
.module('app.controllers', ['ng'])
.controller('sidebarContr', [
/******/ '$scope', '$location',
function ($scope, $location) {
if ($location.path() === '/') {
$scope.file = 'include_0.html';
else {
$scope.file = 'include_1.html';
}
}
])
);
in your HTML:
<div id="sidebar" ng-controller='sidebarContr'>
<div ng-include src='file'></div>
</div>
EDIT: The Angular-UI Router component that you mention seems to be what you need, it looks more powerful. But my solution can be useful when you just need something simple and do not want to have one more dependency.

Resources