Inclusion of Angular into HTML is being tricky - javascript

I am trying to extend my knowledge of JS by learning angular or at the very least get an understanding of angular. I am trying to go through this tutorial but I can not get my downloaded version of angular to load.
I have tried replacing my copy of of the js file with the one included on the GitHub for the tutorial and that works but when I try and link to my local copy it breaks.
This code doesn't work but as soon as the angular file is replaced with one from the repo it works. The two copies of angular are in the same lib folder and I have double checked the names. I have also tried using Google's CDN but that doesn't work either.
Any thoughts on why angular would be acting up this way?
<!doctype html>
<html ng-app>
<head>
<title>Sample AngularJS Controller</title>
</head>
<body>
<div ng-controller="TestCtrl">
<h1>{{title}}</h1>
<input type="text" ng-model="title">
</div>
<script src="lib/jquery-v1.11.1.js"></script>
<script src="lib/angular.js"></script> <!--Fresh Download-->
<!--If I replace the angular.js link with this it works.-->
<!--<script src="lib/angular-v1.2.22.js"></script>-->
<script>
function TestCtrl($scope) {
$scope.title = "Example title! (Change or delete me)";
};
</script>
</body>
</html>

Related

Simple AngularJS 1.5.9 Component Not Rendering in MVC 5

I am trying to get AngularJS 1.5.9 up and running an MVC 5 application using a very simple component called configuration-list.
I created an MVC 5 application (4.5.2), added the Angular.Core 1.5.9 Nuget package
To take MVC 5, layout and razor rendering out of the picture, I created a simple file called test.htm:
<!DOCTYPE html>
<html ng-app>
<head>
<title></title>
<meta charset="utf-8" />
<script src="Scripts/angular.js"></script>
<script src="Scripts/app/module.js"></script>
</head>
<body>
<configuration-list></configuration-list>
</body>
</html>
And in module.js:
(function () {
"use strict";
angular.module("radar", []).component("configuration-list", {
template: "Hello from configuration list"
});
}());
The browser (IE 11) comes up empty.
I have opened the debugging tools and go to the console tab, and there are no errors logged.
I have put a breakpoint in module.js and it is hit (so I know the code is running)
I have tried moving the scripts below the component in the body tag
I have tried setting ng-app="radar" in the html tag
Any idea what I'm missing?
For components the naming has to be camelcase, not hyphencase
angular.module("radar", []).component("configurationList", {
template: "Hello from configuration list"
});

create controller in ng-view page

I want to manage my controller specific to an ng-view page, therefore I put the controller in ng-view page and used that controller specific to that page only. However, the code does not show what it should show from that controller.
Here is my case.
I split my code into 3 files, which are "mainfile.php", "page1file.php", and "page2file.php". "mainfile.php" contains main page which routes to page 1 and page 2. To compare the results, I created different conditions for those 2 pages. "page1file.php" uses controller which has been defined in "mainfile.php", while "page2file.php" uses controller which is defined in the page itself.
In this circumtances, "page1file.php" successfully shows what I want, but "page2file.php" does not show what it should show. Please help me and give a very simple explanation and a simple solution since I'm very new to angularjs.
Here is my code. You can just copy them and run it on your php server.
mainfile.php :
<!DOCTYPE html>
<html>
<head>
<title>learn angular routing</title>
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.min.js"></script>
<script type="text/javascript">
function routeReload($scope) {
$scope.routeReloading = function(){
window.location.reload();
};
}
routeReload.$inject = ['$scope'];
function routeConfig($routeProvider) {
$routeProvider
.when('/one',{
templateUrl:'page1file.php'
})
.when('/two',{
templateUrl:'page2file.php'
})
;
}
routeConfig.$inject=['$routeProvider'];
function testOne($scope) {
$scope.name = "page one";
}
testOne.$inject = ['$scope'];
var testNgView = angular.module('testNgView',['ngRoute']);
testNgView.config(routeConfig);
testNgView.controller('routeReload',routeReload);
testNgView.controller('testOne',testOne);
</script>
</head>
<body>
<div ng-app="testNgView">
<div ng-controller="routeReload">
View page <a ng-click="routeReloading();" href="#one">one</a> or
<a ng-click="routeReloading();" href="#two">two</a>
<div ng-view></div>
</div>
</div>
</body>
</html>
page1file.php :
<div ng-controller="testOne">
This is {{name}}
</div>
page2file.php :
<script type="text/javascript">
function testTwo($scope) {
$scope.name = "page two";
}
testTwo.$inject = ['$scope'];
testNgView.controller('testTwo',testTwo);
</script>
<div ng-controller="testTwo">
This is {{name}}
</div>
I don't think you can inline script modules in your view templates. Have a look at this working version of your app, the way I would organize it:
http://plnkr.co/edit/nSsagK1Y04akNJyMToah?p=preview
You can use .php files in place of the .html files, that shouldn't make a difference.
So your main file should look something like this:
<!DOCTYPE html>
<html>
<head>
<title>learn angular routing</title>
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.min.js"></script>
</head>
<body>
<div ng-app="testNgView">
View page one
or two
<ng-view></ng-view>
</div>
<script src="app.module.js"></script>
<script src="app.routes.js"></script>
<script src="views/page1/controller.js"></script>
<script src="views/page2/controller.js"></script>
</body>
</html>
If your goal is to use PHP to dynamically render your controllers, see the answer to this SO question: Angularjs: server side (php) rendering and data binding client side after an event
You may also be interested in this article, about loading Angular components after the application has been bootstrapped: http://www.bennadel.com/blog/2553-loading-angularjs-components-after-your-application-has-been-bootstrapped.htm
TL;DR: You would need to store a reference to $controllerProvider in the config phase, and then call $controllerProvider.register('MyController', MyController) in your inline script. I'm not sure how I feel about that though...

NG include scope

I've read tons regarding ng-include scope issue but none seem to address the simple thing I'm trying to do. Hope someone can clarify.
This is a simplified version of what I'm trying to do but encapsulates the issue .
Here's the main page
<!DOCTYPE html>
<html lang="en" ng-app="MyApp">
<head >
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/simple-sidebar.css" rel="stylesheet">
</head>
<body>
<script src="js/jquery.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/angular.min.js"></script>
<script>
var app = angular.module('MyApp', []);
</script>
<div ng-include="'/Menu.html'" ></div>
</body>
</html>
and here is Menu.html
<div id="sidebar-wrapper" ng-app="MyApp" ng-controller="MenuController">
<ul class="sidebar-nav">
<li class="sidebar-brand">
<a href="#">
Header
</a>
</li>
<li>
Sign In
</li>
<li ng-repeat="menuItem in MainMenu.Labels">
{{menuItem}}
</li>
</ul>
<script>
app.controller('MenuController', function($scope) {
$scope.MainMenu = {"Labels":["Status","Setup"]} // this code never executes
});
</script>
</div>
How can I create a variable for binding inside menu.html... I can do this outside , but our engine will be generating the menu when that file is requested..
The issue you are facing is not actually a scope issue in this case, but rather how you are setting up your angular app. By putting the code that initializes and assigns the controller to the app in the include, the MenuController is undefined when angular tries to compile the newly included view, and the code will never run, and actually should be throwing errors in the console. I would recommend one of the following:
Remove the angular script from the templates themselves and set them up in their own files with the entire app and its modules set up to be initialized before runtime.
While i don't fully understand what you mean by Engine generating the Menu - it sounds like you are trying to use a template language to actually generate the literal javascript between the script tags from a view model of sorts to set the values. If this is the case, I would advise against this and use an angular service and the $http provider to make an ajax call to set those values in memory.
If you must structure your app this way, you will have to look into lazy loading the controller with a library like this one - https://github.com/matys84pl/angularjs-requirejs-lazy-controllers. I have not used it but from a quick browse through the readme, it appears it might be able to solve your issue will maintaining the structure of your app.

Running Controller in Angular and phpStorm

I'm new to angular and I'm learnign it using phpStorm tool.
It looks like I've done everything right, but I still can't get the right result when I execute the following html and Javascript codes, I did lots of researches on this and made sure that I followed the solutions provided without getting a step ahead:
index.html
<!DOCTYPE html>
<html ng-app="myApp" >
<head >
<title>Ang Tut</title>
<meta charset="UTF-8">
</head>
<body>
<h1>Groups</h1>
<div ng-controller="GroupController">
<ul>
<li ng-repeat="group in groups" ng-model="group.group_name">
{{group.group_name}}
</li>
</ul>
</div>
</body>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript" src="app.js"></script>
</html>
and my app.js file:
var app = angular.module("myApp", []);
app.controller("GroupController", function($scope){
$scope.groups= [
{"id":"144","group_name":"new grouppp"},
{"id":"303","group_name":"Combination group"},
{"id":"323","group_name":"pcb"}
]
});
Same code is working, angular.min.js may not included properly, access your index.html file using http:// instead of file://
var app = angular.module("myApp", []);
app.controller("GroupController", function($scope){
$scope.groups= [
{"id":"144","group_name":"new grouppp"},
{"id":"303","group_name":"Combination group"},
{"id":"323","group_name":"pcb"}
]
});
<!DOCTYPE html>
<html ng-app="myApp" >
<head >
<title>Ang Tut</title>
<meta charset="UTF-8">
</head>
<body>
<h1>Groups</h1>
<div ng-controller="GroupController">
<ul>
<li ng-repeat="group in groups" ng-model="group.group_name">
{{group.group_name}}
</li>
</ul>
</div>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</html>
I had to change the js file, so to include "function()" at the beginning of it, and also "()" at the end line. That solved the problem
You have to include ngRoute in your project.
<script src="angular-route.js"> You can get this file here.
And in your app.js
var app = angular.module("myApp", ['ngRoute']);
And it will start working correctly.
Now, the reason this works in jsFiddle but not locally.
That is because if you look at left pane in jsFiddle under Frameworks & Extensions, you will find the selected option to be no wrap - in <body>
Which means that the code you write in javascript block of js fiddle will be placed inside the body tag the the generated html and therefore, you don't need ngRoute.
But while running locally, I see you have your module initialization in different file viz. app.js that is where ngRoute comes into picture.
In older versions of angular ngRoute was included in angular itself. But in latest versions (not sure from which versions) the ngRoute module is provided separately.

Create pages with pre-compiling the templates

In my current project, my work is only with html and css (HTML skinning). There are many pages which have repeated sections like Header, footer, sharing links etc.
I don't want to repeat this common sections again and again in each page. I want these repeated sections to call somehow using gulp or any other task runner.
Something like this for example (using lodash)
Index.html
<!Doctype html>
<html>
<%= _.template(templates['head'])() %>
<body>
<%= _.template(templates['header'])() %>
<!-- some unique content here -->
<%= _.template(templates['footer'])() %>
</body>
</html>
and then using gulp-template rendering it in each page. I am preferring lodash because I had already worked with it.
As you can see, I am assuming that if somehow I keep the repeating sections in a javascript object (with name templates), I can call it in one line code. And then if I change something in that repeating section, the change will occur in all pages.
To make this possible, first I need to generate the javascript object with that repeating html as string in it.
Can someone please tell me how to do this? or is there any better way to do this?
You can use Jade - node template engine
It gives option to include external jade files, where in it allows you to insert the contents of one jade file into another
index.jade:
doctype html
html
include ./includes/head.jade
body
h1 My Site
p Welcome to my super lame site.
include ./includes/foot.jade
head.jade
//- includes/head.jade
title My Site
script(src='/javascripts/jquery.js')
script(src='/javascripts/app.js')
foot.jade
//- includes/foot.jade
#footer
p Copyright (c) foobar
Compiles to:
index.html
<!doctype html>
<html>
<head>
<title>My Site</title>
<script src='/javascripts/jquery.js'></script>
<script src='/javascripts/app.js'></script>
</head>
<body>
<h1>My Site</h1>
<p>Welcome to my super lame site.</p>
<div id="footer">
<p>Copyright (c) foobar</p>
</div>
</body>
</html>
Explanation:
Whenever I used to search on google for "pre-compiling templates", I was ending up on sites which were combining all the HTML template files to one single js file. But in my case, I was looking for a way to compile the templates completely on system itself with no support of a "all template compiled js file". (So, I was looking for a solution which pre-renders the HTMLs)
Solution:
I found this awesome template engine, Nunjucks, which lets me compile the HTML templates to Independent HTML pages when used with gulp.
Check this one, gulp-nunjucks-render. By using this along with gulp, I am able to include section of .html files into other .html files. Here is the code (assuming you installed nodejs and gulp):
var gulp = require('gulp');
var nunjucksRender = require('gulp-nunjucks-render');
gulp.task('default', function () {
nunjucksRender.nunjucks.configure(['templates/'], { watch: false });
return gulp.src('templates/!(_)*.html')
.pipe(nunjucksRender({
css_path: "../assets/css/",
js_path: "../assets/js/",
img_path: "../assets/images/"
}))
.pipe(gulp.dest('html'));
});
gulp.task('watch', function () {
gulp.watch(['templates/*.html'], ['default']);
});
In the above code, I am keeping the HTML templates in templates folder and with the above gulp code, I am generating the new HTMLs in html folder. The above code will not generate the files which are prefixed with _. (something similar to sass)
and later in command prompt:
gulp watch // Watches the files for changes continuously --> OWNING :D
Here is an example:
<!-- // Index.html -->
<!DOCTYPE html>
<html>
{% include "_head.html" %}
<body>
{% include "_content.html" %}
{% include "_footer.html" %}
</body>
</html>
Which renders to:
<!DOCTYPE html>
<html>
<head>
<title>Website title</title>
<link rel="Stylesheet" href="../assets/jcss/main.css" type="text/css"/>
</head>
<body>
<div class="page">
<!-- content here -->
</div>
<div class="footer">
<!-- footer content here -->
</div>
</body>
</html>
Advantages:
No need of server support to compile the templates.
No need to include any pre-compiled js file in index.html.
Whenever we do some change in common section, no need to include that section again in every page.
Disadvantages:
Till now, I didn't find any :).

Categories