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
Related
I have a problem. I create a component in AngularJs and I want to pass data from controller to Component.
Data comes to template component, but in the controller on component is undefined!
This is my code.
The controller
angular.module('testModule')
.controller('testController', ['$scope',
function($scope){
var vm = this;
vm.name = "John";
}
]);
The component. Here in the console.log(vm.name) its undefined! This is my problem.
angular.module('testModule')
.component('testComponent', {
bindings: {
"name": '='
},
controllerAs: 'ctrl',
controller: ['$scope', function ($scope) {
var vm = this;
console.log(vm);
console.log(vm.name);
}],
template: "<h2>Hi {{ctrl.name}}</h2>",
});
HTML
<html ng-app="testModule">
<head>
<title>Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js"></script>
<script src="app.module.js"></script>
<script src="testController.js"></script>
<script src="testComponent.js"></script>
</head>
<body>
<div ng-controller="testController as ctrl">
<test-component name="ctrl.name"></test-component>
</div>
</body>
</html>
Here is the Plunker
Any idea? Thanks!
You should be hooking up over $onInit method to see what component bindings has.
vm.$onInit = function(){
console.log(vm.name);
}
The things which you were trying to do was totally doable till angular 1.5.X, but since AngularJS 1.6+ version they disabled prepopulating context of controller by introducing preAssignBindingsEnabled over $compileProvider. By default it is set to false. If you really want to see this working you could try to set the flag by below code(but I'd not recommend to use this). The main reason behind introducing this change is to make Angular and AngularJS API to look similar by design & architecture, eventually it will make one step closer to migration to Angular.
.config(function($compileProvider){
$compileProvider.preAssignBindingsEnabled(true);
})
Plunker
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.
I'm trying to implement a text editor with textAngular in a CodeIgniter view, but it keep returning this error:
angular.js:13424 Error: [ng:areq] Argument 'wysiwygeditor' is not a function, got undefined
http://errors.angularjs.org/1.5.3/ng/areq?p0=wysiwygeditor&p1=not%20a%20function%2C%20got%20undefined
Where 'wysiwygeditor' is the name on ng-controller.
I've found tens of questions about that, and all seems to be caused by the same mistakes:
Unnamed ng-app directive
Omitted second argument on module definition
angular.module('myApp', [])
Version incompatibilities on controller declaration
None of those happens to be the problem, and I'm simply copying a code that already works. It's the demo.html from textAngular-1.5.0. I copy the code to a CodeIgniter view, include all the required libraries, but still get the error. Then I noticed it's happening whenever I declare a controller with Angular JS.
To make a better example:
<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js'></script>
<div ng-app="myApp">
<div ng-controller="GreetingController">
{{greeting}}
</div>
</div>
<script>
var myApp = angular.module('myApp',[]);
myApp.controller('GreetingController', ['$scope', function($scope) {
$scope.greeting = 'Bom dia!';
}]);
</script>
This code gives that error on CodeIgniter, but if I put it in a simple html file, works normally.
Here is your edited working code...
Dont use editor, Its waste of your time, They are mostly not working , some time its working...
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js"></script>
<body>
<div ng-app="myApp" >
<div ng-controller="GreetingController">
{{greeting}}
</div>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('GreetingController', function($scope) {
$scope.greeting= "John";
});
</script>
</body>
</html>
My fault, my project was declaring an ng-app on a parent element, in a template file that I've forgot that existed. Removed this tag, and AngularJS stop returning that error.
I'm trying to build an angularjs application. Everything seems fine, there is no error, but it's not working. To remove other factors, I removed everything (requirejs etc.) and dumbed it down to a small html file.
Here is the js code in html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script>
angular.module('application', ['ngRoute']);
angular.module('application').config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/', {template: 'test content', controller: 'controller1'});
$routeProvider.otherwise({redirectTo: '/'});
}]);
angular.module('application').controller('controller1', ['$scope', function($scope) {
console.log('in controller1');
}]);
angular.bootstrap(document, ['application']);
</script>
</head>
<body>
</body>
</html>
Result I'm expecting to see is "test content" on page, and 'in controller1' in my console.
Can you tell me why it's not working?
Your are missing the ng-view directive that works together with the routes to display the template provided in the route config.
Working plunker
Code:
<body>
<div ng-view></div>
<script>
angular.module('app', [])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/', {template: '<p>test content</p>', controller: 'controller1'});
$routeProvider.otherwise({redirectTo: '/'});
}])
.controller('controller1', ['$scope', function($scope) {
console.log('in controller1');
}]);
angular.bootstrap(document, ['app']);
</script>
</body>
Angular JS bootstraps by using ng-app and ng-controller directive declared in html.
Refer this:
http://docs.deployd.com/docs/collections/examples/a-simple-todo-app-with-angular.md
Try adding adding this document ready test around you bootstrap call. It'll wait to call bootstrap until the document (DOM) is completely ready.
If you don't wrap bootstrap in the ready() call the browser may still be in the middle of constructing the DOM when angular builds it's view of the DOM. This can lead to angular being unaware of parts of your page, or worse (and this can be tough to debug).
angular.element(document).ready(function() {
angular.bootstrap(document, ['application']);
};
You can read more about that in this guide to angular initialization: http://docs-angularjs-org-dev.appspot.com/guide/bootstrap
Or you could use <html ng-app='application'> instead as others have mentioned if you want to go the more traditional route- but then you'd have to get rid of the angular.bootstrap call.
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