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
Related
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!!!
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
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
I have a AngularJS SPA application. The main page includes an ng-view directive and a textbox with ng-model bind.
I have some views that display inside ng-view. I have a variable is shared between these views so I used a service for that.
My Issue is when I click a button inside the views this variable changed. I want to display the changed value inside the textbox in main page as soon as it changed.
My Code is As below:
<div data-ng-app="demoApp">
<div ng-controller="testController">
{{countResult}}
</div>
<ng-view class="content"></ng-view>
</div>
I update counterResult inside view which is loaded in ngview. I want the counterResult get updated.
so you want to access a value from outside of the ng-view scope, in the inside of the ng-view scope. check this code, which I've tested on jsbin and it works fine:
index.html:
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular-route.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div data-ng-app="demoApp" ng-init="data.countResult='test'">
<div ng-controller="testController">
Outside ng-view: {{data.countResult}} <br>
</div>
<ng-view class="content"></ng-view>
</div>
</body>
</html>
and your app.js file which you have to add in index.html file:
angular.module('demoApp', ['ngRoute'])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
template: '<div>Inside ng-view: {{data.countResult}}<br><input ng-model="data.countResult"/></div>',
controller: 'viewMainController'
})
.otherwise({
redirectTo: '/'
});
}])
.controller('testController', ['$scope','$rootScope', function($scope, $rootScope){
}])
.controller('viewMainController', function($scope){
});
Here in your testController scope you're defining the countResult value which will not be found in another scope that isn't prototypically inherited from testController. Here you ng-view isn't child of testController so it won't get the value of countResult. So here you can put you countResult value in the $rootScope. As all $scope are children of $rootScope it will get the value in side the ng-view. Hope the explanation make sense.
My html...
<body id="main">
{{pageName}}
</body>
My JS:
angular.module('myApp',[])
.controller('myController', function($scope){
console.log('init');
$scope.pageName = 'My page';
});
angular.element(document).ready(function(){
angular.bootstrap(document.getElementById('main'), ['myApp']);
});
My Resulting HTML:
{{pageName}} instead of 'My Page'
I can do this
<body id="main" ng-controller="myController">
</body>
and it will start working. But, what is the point. Why do I necessarily have to use ng-controller ?
I hope I have made myself clear. Hoping someone would respond to this.
I think the reason is that you are setting pageName in myController but the div cannot use it as the controller is neither defined on it or its parent.
pageName should be set on $rootScope to make it work. You can define that at the run block of module like
angular.module('myApp',[]).run(function($rootScope) {
$rootScope.pageName='My Page';
});
This run block runs after angular has bootstrapped the application. See here
http://docs.angularjs.org/guide/module