ng view not working with custom directive - angularjs

I have recently started learning angularJS and ran into an issue with ng-view directive. Apologies if this question is too naive.
This is my index.html file. As you can see, I am using ng-view directive to abstract out some html code from index.html file.
<!doctype html>
<html lang="en" ng-app="phonecat">
<head>
<meta charset="utf-8">
<title>My first app!</title>
<script src="lib/angular/angular.js"></script>
<script src="js/app.js"></script>
<script src="js/directives.js"> </script>
<script src="js/controllers.js"></script>
</head>
<body>
<div ng-view></div>
</body>
</html>
This is my app.js file. I am using the same partial template for all the urls.
angular.module('phonecat', []).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/phones', {templateUrl: 'partials/searchbox.html', controller: PhoneListCtrl}).
otherwise({templateUrl: 'partials/searchbox.html', controller: PhoneListCtrl});
}]);
and this is my searchbox.html
<div id="container">
<input type="text" name="s" id="s" float-up="{perspective: '100px', x: '150%'}"/>
</div>
and finally this is my directives.js file:
'use strict';
var myAppModule = angular.module('phonecat', []);
myAppModule.directive('floatUp', function() {
return {
// Restrict it to be an attribute in this case
restrict: 'A',
// responsible for registering DOM listeners as well as updating the DOM
link: function($scope, element, attrs) {
console.log("test successful");
}
};
});
When I run this in the browser, the link function of my floatUp directive is never invoked.
When I see the rendered html of my index.html page, I get this (Note that ng-view didn't substitute the searchbox html):
<!DOCTYPE html>
<html class="ng-scope" lang="en" ng-app="phonecat">
<head>
<meta charset="utf-8">
<title>My first app!</title>
<script src="lib/angular/angular.js">
<style type="text/css">
<script src="js/app.js">
<script src="js/directives.js">
</head>
<body>
<div ng-view=""></div>
</body>
</html>
Other observations:
When I remove the directives.js from the index.html file ng-view works perfect and searchbox shows up fine.
When I copy paste the searchbox.html content to the index.html file, the link function is invoked properly.
Is this a known issue? Do custom directives mess up with ng-view and make it futile. I assure you I did extensive googling before posting my question here but couldn't find any appropriate answer.

Move this line from the directives.js
var myAppModule = angular.module('phonecat', []);
to the top of app.js
That way you're always working with the same angular module instance instead of creating new instances of it.
All your controllers, directives, and configs will then be myApModule.controller (or .config, or .directive)
Also in the app.js the references to controller in the routes should be strings controller: 'PhoneListCtrl' as PhoneListCtrl is not defined yet.
Your controllers.js wasn't provided but could look something like this:
myAppModule.controller('PhoneListCtrl', ['$scope', function($scope) {
//Controller code here
}]);
apps.js would now look like this:
myAppModule.
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/phones', {templateUrl: 'partials/searchbox.html', controller: 'PhoneListCtrl'}).
otherwise({templateUrl: 'partials/searchbox.html', controller: 'PhoneListCtrl'});
}]);

Related

AngularJS: ngRouter cannot work

Because the UI-Route cannot work with directive (it has the unbreakable isolated scope) and cannot fit my scenario, I'm testing to remove the UI-Route and go for ngRoute. I spent a day on the ngRoute and it still did not work. I think there must be some subtle mistake in my code but I just cannot figure it out. The simplified test code is as bellow:
<html lang="en" ng-app="Hello" ng-strict-di>
<head>
<title>Hello</title>
<script script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.6/angular.min.js"></script>
<script script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.6/angular-route.min.js"></script>
<script>
'use strict';
angular.module('Hello', ['ngRoute'])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/hello', {
templateUrl: 'hello.html',
controller: 'Ctrl1'
}).otherwise({
redirectTo: "/"
});
}])
.controller('Ctrl1', ['$scope', function ($scope) {
$scope.content = 'Hello World!';
}]);
</script>
</head>
<body>
<div>
<h1>Demo</h1>
click me
</div>
<ng-view></ng-view>
<script type="text/ng-template" id="hello.html">
<p>{{content}}</p>
</script>
</body>
</html>
Really appreciate if you may help me out.
You have to use click me since you are using angular 1.6.x. You have to append an exclamation mark ! to your href.
For more reference: Angular All slashes in URL changed to %2F

angular-ui-router doesn't work

I don't manage to route using ui-router. It does work for me with ng-route, so I must have missed something basic. There is no error but I don't get any view.
The following code does not work (except for the otherwise statement):
angular.module("employeesApp", ["ui.router"])
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('employeeList', {
url: "/employees",
templateUrl: "components/employee_list/employeeListView.html",
});
$urlRouterProvider.otherwise("/employees");
});
The following code does work:
angular.module("employeesApp", ["ngRoute"])
.config(function ($routeProvider) {
var employeeListRoute = {
templateUrl: "components/employee_list/employeeListView.html"
};
var otherwiseRoute = employeeListRoute;
$routeProvider
.when("/employeeList", employeeListRoute)
.otherwise(otherwiseRoute);
Here is my index.html (omitted not relevant elements):
<!DOCTYPE html>
<html lang="en" ng-app="employeesApp">
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.1/angular-ui-router.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular-route.js"></script>
<script src="app.route.js"></script>
<script src="components/employee_list/employeeListCtrl.js"></script>
</head>
<body>
<div>
<ng-view />
</div>
</body>
</html>
What am I doing wrong when trying to use ui-router?
As #AminMeyghani already said, you should be using ui-view instead of ng-view directive to get router know that relative view should be loaded inside ui-view directive
<div>
<ui-view></ui-view>
</div>
Demo here

AngularJS controllers in separate files not identifying the scope

I am learning AngularJS and so far I have the beginnings of a skeleton app, with a main index page and two templates: a login page and a home page which have very simple controllers. I have not reached deeper in the skeleton yet so I am trying to accomplish is much more basic than say authentication.
The reason why I coded the way I did is to try to apply a concept I read about in my time learning AngularJS; which is to modularize your code by giving each template (or partial) it's own controller in it's own JS file. I believe that this is a best practice that I should apply early on, as this will potentially grow a lot into the future. That is the reason why I am staying away from putting my controllers in a single file, which I know works quite well.
Now without further ado, please look at the following code for a reference of where I stand currently:
index.html
<!DOCTYPE html>
<html ng-app="MyApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>MyApp</title>
<link rel="stylesheet" href="assets/css/normalize.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/animate.css">
<link href="https://netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css" rel="stylesheet">
</head>
<body>
<div ng-view>
<!-- loaded view here -->
</div>
<!-- JS imports -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.6.0/lodash.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-route.js"></script>
<script src="assets/js/app.js"></script>
</body>
</html>
app.js
angular.module('MyApp', [
'ngRoute'
])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when("/login", {
templateUrl: 'assets/partials/login.html',
controller: 'LoginCtrl'
})
.when("/home", {
templateUrl: 'assets/partials/home.html',
controller: 'HomeCtrl'
})
.otherwise({
redirectTo: '/login'
});
}]);
login.html, home.html
<div class="container-fluid text-center">
<h2>{{pageTitle}}</h2>
</div>
login.js
angular.module('MyApp')
.controller('LoginCtrl', ['$scope', function($scope) {
$scope.pageTitle = "Hello! Sign In";
}]);
home.js
angular.module('MyApp')
.controller('HomeCtrl', ['$scope', function ($scope) {
$scope.pageTitle = "Welcome to the Home Page!";
}]);
So what is the issue I am working through? {{pageTitle}} is what is being displayed when the view is loaded, rather than the actual value passed in through the scope. Please let me know what is wrong here, I am open to all suggestions regarding how to improve my code, all help is highly appreciated!
You have not included your login.js and home.js to index.html file. Also you do not need to include angular.module('MyApp') in all the file. It is there already in app.js and same instance can be used here too.
You can just do
MyApp.controller('HomeCtrl', ['$scope', function ($scope) {
$scope.pageTitle = "Welcome to the Home Page!";
}]);
MyApp.controller('LoginCtrl', ['$scope', function($scope) {
$scope.pageTitle = "Hello! Sign In";
}]);
You need to include the home.js and login.js controller in html after app.js
<script src="assets/js/app.js"></script>
<script src="assets/js/home.js"></script>
<script src="assets/js/login.js"></script>
You can also create a file name controller.js and add all of the controller in it for simple project, that way you don't have to make new request for js file from html.

Routing Function in AngularJS Does Not Get Executed

Newbie with AngularJS here.
I have an index.html file below, which references an Javascript file named app.js. The index.html file is as below:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script data-require="angular.js#*" data-semver="1.2.22" src="https://code.angularjs.org/1.2.22/angular.js"></script>
<script data-require="angular-route#*" data-semver="1.2.20" src="https://code.angularjs.org/1.2.20/angular-route.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="app.js"></script>
<script src="controller1.js"></script>
</head>
<body>
<h1>Github Viewers</h1>
<div ng-view></div>
</body>
</html>
In my app.js file, I have the following codes:
(function(){
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider){
$routeProvider
.when("/main", {
templateUrl: "main.html",
controller: "controller1"
})
.otherwise({redirectTo: "/main"});
});
}());
I've set breakpoints (in Chrome Dev Tools) on the line:
templateUrl: "main.html",
But I am unable to get into this line.
Console Window shows no errors, so I am a little stumped.
Appreciate any insight on where to look further on this.
You are using the wrong app name.
Change <html ng-app="myApp"> to <html ng-app="githubViewer">
Edit
You cannot put a breakpoint in that line (templateUrl: "main.html"). Note that's an Object definition and not a function:
{
templateUrl: "main.html",
controller: "controller1"
}
And like all Objects, they are defined in an atomic operation. It's like if all its properties were created at once, meaning that you cannot "break" the execution for a specific property.
I've tested with Chrome dev tools and it doesn't even allow me to set a breakpoint in that line. Not sure how you did it...
If you want to check if the "main.html" template is being loaded, watch the network tab of the Chrome dev tools.
I think your dependency injection is missing controller1 module..
if you managing controllers in different module you have to inject it in your app.js
//controller1.js
angular.module('controllers',[])
.controller('controller1',function(....)
//app.js
var app = angular.module("myApp", ["controllers","ngRoute"]);
...
//index.html
...
<script src="controller1.js"></script>
<script src="app.js"></script>
...

How to inherit page appearance?

I have a few pages in my website.
I have a general frame for my website: Top, bottom, and general css are the same for all pages.
What is the convenient way to share the frame between all pages, so that they all look the same.
The AngularJS way to achieve this is by the use of ng-view and routes.
For this, you must include the angular-route file and inject ngRoute in your app. Follow the example:
index.html
<!DOCTYPE html>
<html ata-ng-app="myApp">
<head>
<meta charset="utf-8" />
<title>My App</title>
</head>
<body>
<header><h1> Header for all pages </h1></header>
<div data-ng-view></div> <!-- your files will be rendered here -->
<footer>...</footer>
<script src="path/to/angular.min.js"></script>
<script src="path/to/angular-route.min.js"></script>
<script src="path/to/app.js"></script>
</body>
</html>
app.js
angular.module('myApp', ['ngRoute'])
.controller('PageCtrl', ['$scope', function($scope) {
$scope.title = "The Title";
}])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider.
when("/", {
templateUrl: "path/to/page.html",
controller: "PageCtrl"
}).
}]);
page.html
<h3> {{ scope.title }} </h3>

Resources