I am new to Angular JS and was studying through tutorial and then found something weird.
Let us assume in a JS file i have defined a controller as
//Create the module
var myApp = angular.module("myModule", []);
// Creating the controller and registering with the module all done in one line.
myApp.controller("myController", function ($scope) {
$scope.message = "AngularJS Tutorial";
});
Now i have created a html page where i use this controller
<!doctype html>
<html ng-app="myModule">
<head>
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/Script.js"></script>
</head>
<body>
<div ng-controller="myController">
{{ message }}
</div>
<div>
{{ message }}
</div>
</body>
</html>
This returns me Output as
AngularJS Tutorial
Now when i wrongly type the name of controller
<!doctype html>
<html ng-app="myModule">
<head>
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/Script.js"></script>
</head>
<body>
<div ng-controller="myController">
{{ message }}
</div>
<div ng-controller="myController1">
{{ message }}
</div>
</body>
</html>
In this case it gives
AngularJS Tutorial
{{ message }}
Now though the myContoller1 does not exists and i get a error also but still
{{message}} not exists in 1st try(1st method where no controller defined in div) and should have been printed same as it is.
Can anyone explain me this behavior?
Scope of controller will only applicable within a DOM on which it applied.
In first case you didn't see {{message}} value in second div because you had that binding outside myController div. It would have work if you have wrapped bindings in myController div.
<div ng-controller="myController">
<div>
{{ message }}
</div>
<div ng-controller="myController1">
{{ message }}
</div>
</div>
Where as in 2nd case you don't have myController1, so angular failed while creating instance of myController1 controller(tip: check console for error, if something doesn't work in JS).
Related
I'm creating a spring-boot web application. I'm new to spring-boot as well as AngularJS and have tried integrating this with my application without any success. I have a page of JSON that I want to format as a table in my HTML page ("index.html") but my AngularJS variables are not visible on this page. I formatted some of my HTML code based off this tutorial on YouTube: https://www.youtube.com/watch?v=fUtVRKoBlbQ&list=PLVApX3evDwJ1i1KQYCcyS9hpSy_zOgU0Y&index=6 . I have attached the page of JSON along with my JavaScript code, HTML file, and the result of compiling my program:
JavaScript:
var app = angular.module("User", []);
app.controller("UsersController", function($scope, $http) {
$http.get("http://localhost:7070/user/all")
.success(function(result) {
$scope.tickets = result.tickets
})
});
HTML:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:insert="fragments.html :: headerfiles">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script type="text/javascript" src="/static/app/users.controller.js" th:src="#{/app/users.controller.js}"></script>
</head>
<body>
<base href>
<header th:insert="fragments.html :: nav"></header>
<!-- Page content goes here -->
<div class="container">
<p>This is User\Index. Only people with role_user can see this.</p>
<div ng-app="User" ng-controller="UsersController">
<ul>
<li ng-repeat="t in tickets">
{{t.ticket_id}} - {{t.title}} - {{t.body}}
</li>
</ul>
</div>
</div>
</body>
</html>
JSON:
A screenshot of the tickets (JSON) (
RESULT:
A screenshot of the result when I compile my code
Please note that I highly doubt this is the best solution. It worked for me so I'll post it here. In my HTML file, I moved my starting body tag <body> to line 4, immediately underneath the starting head tag <head th:insert="fragments.html :: headerfiles">. I also removed static as suggested by Ciao Costa in the earlier answer, https://stackoverflow.com/users/4405995/caio-costa . Here is the link on removing the static: (Image does not show using thymeleaf and spring) . Another small change I made was changing the variable {{t.ticket_id}} to {{t.id}} but that's only because the JSON showed it as id
HTML:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:insert="fragments.html :: headerfiles">
<body>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script type="text/javascript" src="/app/users.controller.js" th:src="#{/app/users.controller.js}"></script>
</head>
<base href>
<header th:insert="fragments.html :: nav"></header>
<!-- Page content goes here -->
<div class="container">
<p>This is User\Index. Only people with role_user can see this.</p>
<div ng-app="User" ng-controller="UsersController">
<ul>
<li ng-repeat="t in tickets">
{{t.id}} - {{t.title}} - {{t.body}}
</li>
</ul>
</div>
</div>
</body>
</html>
RESULT:
Since your screen still displays the {{ }}, we know ng-app hasn't initialized properly. A good first approach would be to have a look at the Console, since failing to initialize ng-app usually results in a error message.
If ng-app had initialized, even if the variable you were trying to access in scope was undefined, you would not see the curly brackets.
When AngularJS initializes correctly and doesn't find the variable you are trying to render in DOM, it just leave its space blank and moves on like nothing happened. It also shows no error message in such cases.
I've done some tests and I believe the problem is in here:
<script type="text/javascript" src="/static/app/users.controller.js" th:src="#{/app/users.controller.js}"></script>
It looks like th:src is breaking your application because it is unable to find the file and thus generates a module error.
Try using it this way:
<script type="text/javascript" src="/static/app/users.controller.js" th:src=b"#{baseUrl + '/app/users.controller.js'}"></script>
Or:
<script type="text/javascript" src="/static/app/users.controller.js" th:src="#{~/app/users.controller.js}"></script>
If none of the above work, try removing the static.
Sometimes it happens when you forget to hit ng serve inside your terminal.
I tried doing some input validation on my inputs at my ejs template using angular, but it doesn't seem to be working correctly, this is the code i used (from w3schools):
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body ng-app="">
<p>Try writing in the input field:</p>
<form name="myForm">
<input name="myInput" ng-model="myInput" required>
</form>
<p>The input's valid state is:</p>
<h1>{{myForm.myInput.$valid}}</h1>
</body>
</html>
It's supposed to ouput something like this:
The input's valid state is: false
But instead it just returns this:
The input's valid state is: {{myForm.myInput.$valid}}
So is it in any way possible to use ejs and angular together?
You need to have a module and a controller defined, script should be loaded inside the body/head
HTML
<!DOCTYPE html>
<html ng-app="store">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-app="">
<form name="myForm">
<input name="myInput" ng-model="myInput" required>
</form>
<p>The input's valid state is:</p>
<h1>{{myForm.myInput.$valid}}</h1>
</body>
</html>
Controller
var app = angular.module('store', []);
app.controller('StoreController', function($scope) {
});
DEMO
<html ng-app="insert_app_name_here">
<body ng-controller="insert_controller_name_here">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
</body>
</html>
I would set up my angular app like the above code. Also, including the script at the end of your body tag is good practice. Moreover, removing the .min from your script tag to just angular.js instead of angular.min.js helps you debug your code better since you will be using it for development and not for production.
In setting up your app, I would include an app.js file where the code goes like this:
angular.module('insert_app_name_here', [])
In setting up your controller, I would include a controller file (i.e. mainCtrl.js) where the code goes like this:
angular.module('insert_app_name_here').controller('insert_controller_name_here, function($scope) {
});
As to linking angular with ejs, i am unfamiliar with ejs, therefore i cannot provide a solution for that.
I'm learning AngularJS and I have problem with data binding.
When I try to get value from $scope.mytext i get {{mytext}}. Here is the code:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>Hello</title>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js">
</script>
<script>
var MainController = function ($scope) {
$scope.mytext = "Angular JS Rulez";
}
</script>
</head>
<body>
<div ng-app>
<div ng-controller="MainController">
<p>{{mytext}}</p>
</div>
</div>
</body>
</html>`
You had some errors in the way you set up the app.
You never defined the app, you have declared ng-app twice, the second time you haven't assigned anything to ng-app and there was an error with the CDN you referenced. Once you defined the app, you then needed to assign the controller to this app.
The below code will work for you, and you can also see the code working by checking out this jsfiddle demo.
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>Hello</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script>
var myApp = angular.module('myApp',[]);
myApp.controller('MainController', ['$scope', function($scope) {
$scope.mytext = "Angular JS Rulez";;
}]);
</script>
</head>
<body>
<div ng-controller="MainController">
<p>{{mytext}}</p>
</div>
</body>
</html>
Looks like you're calling the app in the html, but you haven't defined it anywhere. You must:
define 'myApp' in the javascript portion, and then
assign the controller on it.
Your code simply calls MainController which isn't defined properly on any app.
A basic setup in this case is, as Paul mentions:
var myApp = angular.module('myApp', []);
myApp.controller(MyAppController, ['$scope', function($scope) {
...add $scope elements here ...
]);
Also you shouldn't need to call ng-app twice in the html.
I am new to Angular and JavaScript. I want to use ng-include to import elements form htmls, the elements are simple for display. To illustrate, here I have 3 html files, "123.html", "456.html", and "789.html".
For "123.html":
<!DOCTYPE html>
<html>
<head>
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body ng-app="myApp">
<p> Here we have 123. </p>
<div class="container">
<div ng-include="'456.html'"></div>
<div ng-include="'789.html'"></div>
</div>
</body>
</html>
For "456.html":
<div>
<P> Here is the 456. </P>
</div>
And for "789.html":
<div>
<P> And here is the 789. </P>
</div>
I see some ng-include examples, but all of them got ng-controller and additional JavaScript file. So my question is, if I just want to display html elements, do I still need ng-controller for the code?
P.S. The code above cannot correctly work, could someone help figure out the problem for this very simple example? The browser is Firefox. Thanks.
Angular must at least have the module myApp available since that's what you are declaring in ng-app
It can't bootstrap without that module and errrors in your browser console should be telling you that it can't find it.
If all you are doing is using angular for includes why not just use server side includes?
So you don't have an app called myApp and would get an error referencing a module that is not defined. In the code below you can see I removed it.
That being said you can define templates using the script tag with ngTemplate.
<script type="text/ng-template" id="456.html">
<div>
<P> Here is the 456. </P>
</div>
</script>
Example using both a script template and a separate file.
This is the full working code:
<!DOCTYPE html>
<html>
<head>
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body ng-app>
<p> Here we have 123. </p>
<div class="container">
<div ng-include="'456.html'"></div>
<div ng-include="'789.html'"></div>
</div>
<script type="text/ng-template" id="456.html">
<div>
<P> Here is the 456. </P>
</div>
</script>
<script type="text/ng-template" id="789.html">
<div>
<P> And here is the 789. </P>
</div>
</script>
</body>
</html>
I have following ng-repeat
<div ng-repeat="page in pages">
<input type="text" ng-model="page.name"
</div>
Basically this will show page.name multiple times for same name. Problem is my data being returned is in collection so I cant just use the name property.
Can you please tell me how can i just show page.name only once.
I'd still say your better off pulling this data into it's own property but here's a lazy way to achieve the goal:
HTML
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#*" data-semver="1.2.14" src="http://code.angularjs.org/1.2.14/angular.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="myApp" ng-controller="MyCtrl">
<input type="text" ng-model="pages[0].name"/>
</body>
</html>
JS
// Code goes here
angular.module("myApp", []).controller("MyCtrl", function($scope){
$scope.pages = [{name:"Page1"},{name:"Page2"}];
})
Plunkr: http://plnkr.co/edit/UmRSVek3psKoklxVKBfI?p=preview