How to use <md-progress-linear> in AngularJS MD? - javascript

I am using Material Design in my AngularJS app and I want to add a progress bar while my page is loading.
MD uses md-progress-* Directive to get a loading bar:
<md-progress-linear md-mode="determinate" value="..."></md-progress-linear>
In my app I tried to get loading progress complete on $viewContentLoaded:
HTML:
<html ng-app="app">
<body ng-controller="AppCtrl">
<md-progress-circular ng-if="determinateValue === 100" md-mode="determinate" value="{{determinateValue}}"></md-progress-circular>
...
</body>
</html>
JS:
'use strict';
angular.module('app', ['ngMaterial', 'ngAnimate'])
.controller('AppCtrl', function ($scope) {
$scope.determinateValue = 0;
$scope.$on('$viewContentLoaded', function(){
$scope.determinateValue = 100;
});
});
But it doesn't work and I do not get any error.
ps. the <md-progress-linear> tag is disappeared from the DOM.

Firstly, use md-mode="indeterminate" as your loading is binary and has only two states. get rid of the ng-if and use the value attribute bound to $scope.determinateValue. So:
<md-progress-circular md-mode="indeterminate" value="determinateValue"></md-progress-circular>
I'd rename the determinateValue to something more precise and reflective also. Also the tag disappears cause the determinateValue is always at some point being assigned to 100 ie your content is loading

Related

Create angular module after timeout is not working

I am trying to delay the module creation, but it doesn't work (I am using Chrome). Here is my code TRY THE JSFIDDLE
<!doctype html>
<html>
<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.min.js"> </script>
</head>
<body>
<div ng-controller="MyCtrl">
Hello, {{name}}!
</div>
<script>
//initApp();
setTimeout(initApp, 1000);
function initApp() {
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl',
function($scope) {
$scope.name = 'Superhero';
});
}
</script>
</body>
</html>
If I remove the setTimeout and simply call initApp(), then it works. Can anyone explain why?
I am trying to embed an angular app into a page, and I am not allowed to add script tags to the HEAD. So I have to figure out some way to postpone the angular module initialization until after the angular.min.js is loaded and parsed.
It's not how you do it in angular way.
First i don't see any ng-app tag so your controler won't ever be called.
Second in order to delay the bootstrapping (and not using ng-app tag) you use angular.boostrap :
//initApp();
setTimeout(initApp, 1000);
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl',
function($scope) {
$scope.name = 'Superhero';
});
function initApp() {
angular.bootstrap('myApp');
}
For dynamic loading of javascript file see : lazy loading javascript the second point of the author of the post should do the job.
There is no need to use setTimeout. Browsers parse the JavaScript in the order they are declared in the HTML unless the async attribute is used.

How to write HTML inside elements with Angular

I'm beginning with Angular, and just wanted to make some tests with Ajax, retrieving a document into my page. It works perfectly, but then a new challenge appeared: I want to be able to add HTML inside a DOM element.
Normally, one would do that from a directive and the templates thingy. But I want to do it at runtime, using a controller.
This is my code:
$http.get("import.html").then(function(response){
var element = document.createElement("div");
element.innerHTML = response.data;
angular.element("#div1").innerHTML(element);
});
Maybe I'm not using correctly "angular.element"? I tried using document.getElementByID, but it doesn't work either. I receive correctly the information from the file, but I just don't find a way I can compile that HTML in runtime.
Any help with this?
edit for showing my full code:
HTML:
<!DOCTYPE html>
<html ng-app="miApp">
<head>
<meta charset="UTF-8">
<script src="angular.js"></script>
<script src="mainmodule.js"></script>
<link rel="stylesheet" href="bootstrap/css/bootstrap.css">
</head>
<body ng-controller="controlador1">
<div id="div1" ng-bind-html="myHtml" style="top:50px;left:50px">
</div>
</body>
</html>
JS:
(tested all your examples, none worked for me, this is the last I used)
app.controller('controlador1', ["$scope", "$http", "$sce", "$compile", function($scope, $http, $sce, $compile) {
$http.get("import.html").then(function(response) {
var parent = angular.element("#div1");
var element = angular.element($sce.trustAsHtml(response.data);
$compile(element)($scope);
parent.append(element);
});
}]);
Usually, you want to compile your HTML if it contains any angular functionality at all (you need to declare '$compile' in your controller dependency list):
myApp.controller('myController', ['$scope', '$sce', '$compile'],
$scope, $sce, $compile) {
$http.get("test.html")
.then(function(response){
var parent = angular.element("#div1");
parent.append($compile(response.data) ($scope));
});
}]);
if you are hell-bent on useing innerHTML, note that angular.element("#div1") is the same as $("#div1") in jQuery. So you need to write angular.element("#div1")[0].innerHTML= ...
Here's a plnkr: http://plnkr.co/edit/p3TXhBppxXLAMwRzJSWF?p=preview
In this, I have made use of $sce. It's a dependency injection of AngularJS, where it treats the HTML as safe to bind. You can read about it in AngularJS site. Please find below code and working jsfiddle for the raised concern:
HTML:
<div ng-app="app" ng-controller="test">
<div>
This is onload HTML
</div>
<div ng-bind-html="dynamicHtml"></div>
</div>
JS
var app = angular.module('app', []);
app.controller('test', function ($scope, $sce) {
$scope.dynamicHtml = $sce.trustAsHtml("<div>This is dynamic HTML!!");
});
[Update]
HTML:
<div ng-bind-html="dynamicHtml"></div>`
JS:
$http.get("import.html").then(function (response) {
$scope.dynamicHtml = $sce.trustAsHtml(response.data); //Assuming 'response.data' has the HTML string
});
You are not using correctly angular. If you use angular, you don't harly ever have to use DOM selector.
Scope is binded with ng-model and {{}} on the view.
Now your answer. To print html on the view, you can do it in that way:
In controller:
$http.get("import.html").then(function(response){
$scope.html = $sce.trustAsHtml(response.data);
});
In view:
<div ng-bind-html="html"></div>
And more easy way:
<ng-include="'url/import.html'"><ng-include>
That's it!!!

Load Angularjs controllers in ngView

I'm new to Angular and just started to build a test project to learn it, now have a problem with loading controllers OnDemand.
let's code a bit, I have the following HTML:
index.html
<body>
<div ng-app="MyApp">
CLICK ME
<div ng-view></div>
</div>
<script>
angular.module("MyApp",['ngRoute'])
.config(function($routeProvider) {
$routeProvider.when('/child', {
templateUrl: 'somwhere/child.html',
controller: 'childCtrl' <!-- will remove -->
});
}) <!-- will remove contoller defination below -->
.controller('childCtrl', function($scope) {
$scope.data = DoHeavyCalc();
});
</script>
</body>
what is obvious to me is that I should define my controller exactly where I config my module (MyApp), which doing this depends on DoHeavyCalc() which is not needed right now! (think this method does a big calculation, but it should be run only when the user clicks on the link, not at the beginning of the app).
Now I want to load the and define the controller inside child.html instead of my index.html. OK, so I removed the sections marked in above code and tried to write the child.html like this:
child.html
<div ng-controller="childCtrl">
{{data}}
</div>
<script>
angular.module("MyApp")
.controller('childCtrl', function($scope) {
$scope.data = DoHeavyCalc();
});
</script>
but is causes an error:
[ng:areg] `childCtrl` is not a function. got undefined.
also i tried to put script tag in child.html before the div tag, but it didn't affect anything.
Now my question is, how can i define and load the controller OnDemand and do my heavy work just when the user routes to a certain location not at the beginning of app?
You are asking about lazy loading ! By default angular doesn't support lazy loading, what you can do ? you can use any third party library like requirejs or others.
Currently angularjs doesn't execute any javascript inside templateUrl or template, more details
Here is a working example of lazy loading using requirejs.
Also there is some discussion regarding onDemand script loading
Lazy loading angularjs
In the child.html page do not include ng-controller attribute. Already child.html is associated with the childCtrl controller. Just remove the attribute ng-controller from the child.html page

Add angular app in already existing app and transfer data

i am trying to add angular app in already existing jquery app.
Suppose i have a simple button in html.
I am trying to load angular app and run controller code on button click. I load the angular app mannually using angular.bootstrap(document, ['myApp']) . and also i am trying to pass some data from jquery to angular app. Can it be possible??
Have a look-
<!DOCTYPE html>
<html>
<head lang="en">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<title>jA</title>
</head>
<body>
<button id="myButton" value="25">Hello world</button>
</body>
<script>
angular.module('myApp', []) // I defined the angular app.
.controller('MyController', ['$scope', function ($scope) {
console.log('Hello world'); // This should run on button click.
}]);
$(document).ready(function () {
$("#myButton").click(function(){
var some_value = '25'; //value i am trying to pass to angular app to use in angular app.
angular.bootstrap(document, ['myApp']); //load angular app
});
});
</script>
</html>
jQuery and AngularJS don't "talk" to each other directly, but Angular does "see" any other native javascript you have, so lets say - if you define a global variable and change it via jQuery when AnuglarjJS will access it - it can read and use the value.
Giving your example - who's using/calling MyController ?
check out the fiddle I've created for you as an example: https://jsfiddle.net/b29rng12/2/
<div id="myAngularApp">
<button id="myButton" value="25"> click to bootstrap</button>
<p ng-controller='MyController'>
this section will be bind to the controller. {{ test }} and the value is {{ some_jquery_value }}
</p>
</div>
<script>
var some_value = '25'; //value i am trying to pass to angular app to use in angular app.
angular.module('myApp', []) // I defined the angular app.
.controller('MyController', ['$scope', function ($scope) {
console.log('Hello world'); // This should run on button click.
$scope.test = "ricky";
$scope.some_jquery_value = some_value; // This is your predefined variable
}]);
$("#myButton").click(function(){
some_value = 30;
angular.bootstrap($("#myAngularApp"), ['myApp']); //load angular app
});
</script>
So just to explain - the app starts when its not bootstrapped, this is why you'll see {{ }} instead of values.
After you'll click the button ( as in your example ) - the app is bootstrapped - it still doesn't mean that this code will use the specific controller that you had in mind ( angular module can have 100 controllers - so who will use what ?! )
So I've defined <p ng-controller='MyController'> - is what binds the controller after the app has been bootstrapped.
I hope it helps ....

dynamic routing AngularJS

I am trying to bind a route property to the src for ng-include:
config.js
$routeProvider.when('/services', {
templatePATH: '/views/services.html'
});
index.html
<html lang="en" ng-app="myApp" ng-controller="AppController">
<body>
<div ng-include src="{{page}}" class="container"></div>
</body>
</html>
controllers.js
controller('AppController', ['$scope','$route','$routeParams', function($scope, $route, $routeParams) {
var render = function(){
$scope.page = $route.current.templatePATH;
};
$scope.$on("$routeChangeSuccess",function( $currentRoute, $previousRoute ){
render();
});
}]).
Here's where I got the idea. What is strange is that the value of templateURL can be seen in the DOM on pageload where src is injected from the ng-include directive. Sadly however, this is not working.
Is it possible to achieve this kind of convention?
Oh your are just making a very small mistake please change your code to below
<div ng-include="page" class="container"></div>
More Detailed Answer :
When you use ng-include directive a watch is put on srcExp which is value of attr.ngInclude || attr.src so if you do {{page}} then you will be watching on the value of page not on page property so you have to put "page" without interpolated value so that it can watch directly on page instead of page string value

Categories