I am new to angular. I have tried creating an application and all was going well until I decided to create a custom directive.
My html looks like this:
<body ng-app="sapphireApp">
<div class="off-canvas-wrap" data-offcanvas>
<div class="inner-wrap">
<nav class="tab-bar">
<section class="middle tab-bar-section">
<h1 class="title">Sapphire</h1>
</section>
<section class="right-small">
<a class="right-off-canvas-toggle menu-icon" href="#"><span></span></a>
</section>
</nav>
<aside class="right-off-canvas-menu" ng-controller="TopController as topController">
<ul class="off-canvas-list">
<li><label>Users</label></li>
<li ng-hide="topController.userService.isLoggedIn">Login</li>
<li ng-show="topController.userService.isLoggedIn">Logout</li>
</ul>
</aside>
<section class="main-section" ng-view></section>
<a class="exit-off-canvas"></a>
</div>
</div>
<script src="scripts/angular.min.js"></script>
<script src="scripts/mm-foundation/mm-foundation-0.5.1.min.js"></script>
<script src="scripts/angular-cookies.min.js"></script>
<script src="scripts/angular-route.min.js"></script>
<script src="scripts/angular-touch.min.js"></script>
<script src="scripts/app/app.js"></script>
<script src="scripts/app/controllers.js"></script>
<script src="scripts/app/services.js"></script>
<script src="scripts/app/directives.js"></script>
</body>
and my four angularJS files look like this respectively:
app.js
angular.module('sapphireApp', ['ngRoute', 'ngCookies', 'ngTouch', 'mm.foundation'])
.config(function ($routeProvider) {
$routeProvider.when('/', {
templateUrl: 'views/home/index.html'
})
.when('/login', {
templateUrl: 'views/account/login.html'
})
$routeProvider.otherwise({
redirectTo: '/'
});
});
controllers.js
angular.module('sapphireApp')
.controller('TopController', ['UserService',
function (UserService) {
var self = this;
self.userService = UserService;
// Check if the user is logged in when the application
// loads
// User Service will automatically update isLoggedIn
// after this call finishes
UserService.session();
}
])
.controller('HomeController',
function () {
var self = this;
}
)
.controller('LoginController', ['UserService', '$location',
function (UserService, $location) {
var self = this;
self.user = { username: '', password: '' };
self.login = function () {
UserService.login(self.user).then(function (success) {
$location.path('/');
}, function (error) {
self.errorMessage = error.data.msg;
})
};
}
]);
services.js
angular.module('sapphireApp')
.factory('UserService', ['$http', '$cookieStore', function ($http, $cookieStore) {
var service = {
isLoggedIn: false,
session: function () {
var user = $cookieStore.get('user');
if (user)
service.isLoggedIn = true;
return user;
},
login: function (user) {
return $http.post('/api/account/login', user)
.then(function (response) {
service.isLoggedIn = true;
$cookieStore.put('user', response);
return response;
});
}
};
return service;
}]);
directives.js
angular.module('sapphireApp')
.directive('square', function () {
return {
restrict: 'E',
template: '<div class="square"><h1>Show something else</h1></div>',
link: function () {
alert("this is working");
}
};
});
The login view works fine, but the home view doesn't. It looks like this:
<div class="row" ng-controller="HomeController as homeController">
<div class="small-2 columns">
<sqaure>
<h1>This is the square</h1>
</sqaure>
</div>
</div>
Now, because I have created the directive square and set it to be an element, I would expect an output like this:
<sqaure>
<div class="square">
<h1>Show something else</h1>
</div>
</sqaure>
and I would also expect there to be an alert. But I get nothing. No errors and the Html stays unmodified.
Can anyone tell me why? I assume because I am getting no errors, it is just a misunderstanding on my part.
You have a typo in the directive:
<sqaure> //typo here
<h1>This is the square</h1>
</sqaure> //typo here
Change sqaure to square.
Related
In my project I am using angular $routeProvider as page navigation. In order to go back I'm using javascript.go(-1). The problem is when the button back was clicked, it's loading and rendering again all the data. Is it possible to save the previous stage in javascript.go(-1)?
Example:
app.config(function ($routeProvider, localStorageServiceProvider) {
$routeProvider
.when('/api/lecturer/', {
templateUrl: 'partials/dashboard.html',
controller: 'dashboardController'
})
.when('/account/lecturer/project/', {
templateUrl: 'part/lecturer_project.html',
controller: 'projectController'
}).otherwise({redirectTo: '/login'});})
HTML:
<li>
<a onclick="javascript:history.go(-1);" style="cursor:pointer;" class="button">back
<i class="entypo-left-dir right"></i>
</a>
</li>
For a simple implementation, you need to remember the previous page (only one), and store it in some service/factory that will provide the stored value to your controllers. Here is a simple demo with ngRoute:
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: "main.html"
})
.when('/api/lecturer/', {
templateUrl: 'partials/dashboard.html',
controller: 'dashboardController'
})
.when('/account/lecturer/project/', {
templateUrl: 'part/lecturer_project.html',
controller: 'projectController'
})
.otherwise({
redirectTo: '/'
})
});
app.controller('dashboardController', function($scope, historyService) {
$scope.back = historyService.get();
});
app.controller('projectController', function($scope, historyService) {
$scope.back = historyService.get();
});
app.service('historyService', function() {
/* `this.back` can be an array instead,
which will work as a stack,
pushing new previous pages
and popping then when redirected back
*/
this.back = "";
this.get = function() {
return this.back;
}
this.set = function(val) {
this.back = val;
}
this.delete = function() {
this.back = "";
}
})
app.run(function($rootScope, historyService) {
// `$locationChangeStart` event works better for this example
$rootScope.$on("$locationChangeStart", function(event, next, prev) {
//console.log(event);
//console.log(next); // current page
//console.log(prev); // previous page
historyService.set(prev); // store the previous page in a service
});
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular-route.js"></script>
<body ng-app="myApp">
lecturer
project
<hr>
<div ng-view></div>
<script type="text/ng-template" id="main.html">
<p>main.html</p>
</script>
<script type="text/ng-template" id="partials/dashboard.html">
<p>partials/dashboard.html</p>
<a ng-href="#!/">Main</a>
<a ng-href="{{back}}">Go back</a>
</script>
<script type="text/ng-template" id="part/lecturer_project.html">
<p>part/lecturer_project.html</p>
<a ng-href="#!/">Main</a>
<a ng-href="{{back}}">Go back</a>
</script>
</body>
</html>
Could you please let me know what is wrong with my code? I get the initial HTML page, but when I click on "Open", nothing happens. Not even the console logs an error, or any other change.
app.js
var app = angular.module('carApp', ['ui.bootstrap']);
ctrl.js
app.controller('carCtrl', function($scope, $http, $uibModal) {
$http.get('jobs.json').success(function(data) {
$scope.data = data;
$scope.open = function() {
var modalContent = $uibModal.open({
templateUrl: 'careersTpl.html',
controller : modalContentCtrl,
resolve: {
items: function() {
return $scope.data;
}
}
})
}
});
});
var modalContentCtrl = function ($scope, $modalInstance, data) {
$scope.data = data;
$scope.selected = {
item: $scope.data.specs
};
};
JSON:
{
"specs":[
{
"job-title":"TITLE",
"job-apply":"applink",
"job-body":"JOB BODY"
}
]
}
HTML:
<div class="car-up">
<script type="text/ng-template" id="careersTpl.html">
<div class="modal-header">
<h3>Lorem Ipsum</h3>
</div>
<div class="modal-body">
<p ng-repeat="item in data">{{item}}</p>
</div>
</script>
<button class="btn" ng-click="open()">Open</button>
</div>
I'm new to AngularJS, but I have linked the app.js and ctrl.js... thanks.
EDIT: after I've placed ng-controller="carCtrl" in the html file, I receive this error:
Error: [$injector:unpr]
http://errors.angularjs.org/1.5.7/$injector/unpr?p0=%24modalInstanceProvider%20%3C-%20%24modalInstance
O/<#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:6:412
db/n.$injector<#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:43:84
d#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:40:344
db/V<#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:43:144
d#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:40:344
e#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:41:78
h/<.invoke#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:41:163
gf/this.$gethttps://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:89:397
resolveSuccess#https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.2.0/ui-bootstrap-tpls.js:4422:34
e/<#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:130:409
vf/this.$gethttps://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:145:103
vf/this.$gethttps://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:142:165
vf/this.$gethttps://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:145:399
Lc[b]https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:274:444
Sf#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:37:31
Rf/d#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:36:486
Please find working demo
angular.module('carApp', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
var app = angular.module('carApp');
app.controller('carCtrl', function($scope, $http, $uibModal) {
//$http.get('jobs.json').success(function(data) {//Uncomment
//$scope.data = data; Uncomment
//Remove below line from code when you are using this in your project
$scope.data = {
"specs": [{
"job-title": "TITLE",
"job-apply": "applink",
"job-body": "JOB BODY"
}]
}
$scope.open = function() {
var modalContent = $uibModal.open({
templateUrl: 'careersTpl.html',
controller: 'ModalInstanceCtrl',
controllerAs: '$ctrl',
resolve: {
items: function() {
return $scope.data;
}
}
})
}
//});//Uncomment
});
app.controller('ModalInstanceCtrl', function($uibModalInstance, items, $scope) {
$scope.data = items;
console.log($scope.data);
$scope.selected = {
item: $scope.data.specs
};
});
<!doctype html>
<html ng-app="carApp">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-animate.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-sanitize.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.3.0.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="carCtrl" class="modal-demo">
<script type="text/ng-template" id="careersTpl.html">
<div class="modal-header">
<h3>Lorem Ipsum</h3>
</div>
<div class="modal-body">
<p ng-repeat="(k,v) in data.specs">
<span>Title: {{v["job-title"]}}<br/> </span>
<span>Link: {{v["job-apply"]}}<br/> </span>
<span>Body: {{v["job-body"]}}<br/> </span>
</p>
</div>
</script>
<button class="btn" ng-click="open()">Open</button>
</div>
</body>
</html>
Try defining the controller like this outside,
app.controller('modalContentCtrl ', function($scope, $modalInstance, data) {
$scope.data = data;
$scope.selected = {
item: $scope.data.specs
};
}
I have a loading div that I'd like to share across several controllers. Is there a way to accomplish this without placing this template in every other template?
For example:
<div ng-show="loading" class="loading">Loading</div>
Now in my controller I turn this off and on my using $scope.loading = true/false.
In my main page I use this:
<div class="container" ng-app="myApp">
<div ng-view>
</div>
</div>
I'm using routing so, right now I have to place the loading div in each template that is called by the router so it is inserted in ng-view. All I want is one location for the loading div. How do I accomplish this?
Set up the loading div as a custom directive, check out this example from the angularjs documentation:
angular.module('docsSimpleDirective', [])
.controller('Controller', ['$scope', function($scope) {
$scope.customer = {
name: 'Naomi',
address: '1600 Amphitheatre'
};
}])
.directive('myCustomer', function() {
return {
template: 'Name: {{customer.name}} Address: {{customer.address}}'
};
});
http://plnkr.co/edit/?p=preview
There's quite a few ways to do this.
What I've come up with is to use a service to register an AppController callback. Then in each of my page's controllers I inject that service, and call the callback with true/false.
The full code is below, but the main lines to focus on is:
myApp.service('LoadingService', function() {
var controllerCallback = function() {};
this.setControllerCallback = function(callback) {
controllerCallback = callback;
};
this.setLoading = function(bool) {
controllerCallback(bool);
};
});
And in your AppController:
LoadingService.setControllerCallback(function(bool) {
$scope.loading = bool;
});
Then to show the loading div, just inject that service into a controller and call
LoadingService.setLoading(true) //or false
This allows for the service to be reused in any controller that needs to toggle the loading div.
// Code goes here
var myApp = angular.module('app', ['ngRoute']);
myApp.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/page1', {
templateUrl: 'page1.html',
controller: 'PageOneController'
})
.when('/page2', {
templateUrl: 'page2.html',
controller: 'PageTwoController'
})
});
myApp.controller('AppController', function($scope, LoadingService) {
$scope.loading = false;
LoadingService.setControllerCallback(function(bool) {
$scope.loading = bool;
});
});
myApp.controller('PageOneController', function($timeout, LoadingService) {
LoadingService.setLoading(true);
$timeout(function() {
LoadingService.setLoading(false);
}, 2000);
});
myApp.controller('PageTwoController', function($timeout, LoadingService) {
LoadingService.setLoading(true);
$timeout(function() {
LoadingService.setLoading(false);
}, 3000);
});
myApp.service('LoadingService', function() {
var controllerCallback = function() {};
this.setControllerCallback = function(callback) {
controllerCallback = callback;
};
this.setLoading = function(bool) {
controllerCallback(bool);
};
});
<!DOCTYPE html>
<html ng-app="app">
<head>
</head>
<body ng-controller="AppController">
<h1>Title</h1>
Page 1
Page 2
<div ng-if="loading">Loading...</div>
<div ng-view></div>
<script src="https://code.angularjs.org/1.4.3/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular-route.min.js"></script>
<script type="text/ng-template" id="page1.html">
<div>You're on page one</div>
</script>
<script type="text/ng-template" id="page2.html">
<div>You're on page two</div>
</script>
</body>
</html>
I'm trying to get JSON data from my server and display them into my website. I am using Ui-router extension. What I am looking for here is a master-detail setup.
Index.html
<input ng-model="manga.name" ng-change="searchManga()" id="search" type="search" placeholder="Manga İsmi Girin..." required>
<div class="row" ui-view="viewA">
<div class="col s8 offset-s1" ng-controller = "nbgCtrl">
<div class="row">
<div class="col s12 m6 l4" ng-repeat = "manga in mangas">
<div class="row">
<div class="col s5">
<a ui-sref="ui-sref="#/manga/{{manga.id}}"" class="thumbnail">
<img src="/kapaklar/{{manga.kapak}}">
</a>
</div>
<div class="col s7">
<p>{{manga.ad}}</p>
<a href="" class="waves-effect waves-light btn">
</a>
I have above a main page and repeating some thumbnails. Every thumbnail links to its detailed information page. And when clicking a thumbnail it has to carry its own data and load it here. Here's what I've got so far:
JS:
angular.module('nasuh',["ui.router"])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('list', {
url: "/",
controller: "ListCtrl",
templateUrl: "index.html",
}
)
$stateProvider
.state('icerik', {
url: "/icerik/:{{mangaid}}",
controller: "mmgCtrl",
views: {
"viewA": { templateUrl: "icerik.html" },
}
}
)
})
.factory('Mangas', function($http){
var factory = {};
function getData(manganame, callbak) {
var url = '/uzak/remote.php?callback=JSON_CALLBACK';
$http.get(url).success(function(data){
factory = data.results;
callback(data.results);
})
}
return {
list: getData,
find: function(name, callback) {
console.log(name);
var manga = cachedData.filter(function(entry) {
return entry.id == name;
})[0];
callback(manga);
}
};
})
.controller('ListCtrl', function($scope, $http, Mangas) {
$scope.manga = {
name: '' }
$scope.searchManga = function() {
Mangas.list($scope.manga.name, function(mangas) {
$scope.mangas = mangas;
});
}
})
.controller('mmgCtrl', function($scope, $http, $stateParams, Mangas) {
Mangas.find($stateParams.mangaid, function(manga) {
$scope.manga = manga;
});
})
I just doubt that the getData is not a promise in resolve closure you hava returned MY.isimler.then so in mmgCtrl controller first console getData to make sure it's a promise or data
In web application there are a lot of modal template (angular foundation modal). When the modal is opened, we must give controller that are created in the page javascript file. but this controller are generally written inline. I want to get these controller as external or dynamically load.
It is like :
var modalInstance = $modal.open({ templateUrl: 'myModalContent.html',
controller: 'modal-controller.js' })
can it be done? if so, how can I do that this,
thank your helps
Would you try this?
angular.module('foundationDemoApp', ['mm.foundation']);
angular.module('foundationDemoApp').controller('ModalDemoCtrl', function ($scope, $modal, $log) {
$scope.items = ['item1', 'item2', 'item3'];
$scope.open = function () {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
});
// Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $modal service used above.
angular.module('foundationDemoApp').controller('ModalInstanceCtrl', function ($scope, $modalInstance, items) {
$scope.items = items;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function () {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
<!doctype html>
<html ng-app="foundationDemoApp">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.js"></script>
<script src="//pineconellc.github.io/angular-foundation/mm-foundation-tpls-0.5.1.js"></script>
<script src="example.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/foundation/5.2.0/css/foundation.css" rel="stylesheet">
</head>
<body>
<div class="row">
<div class="small-12.columns">
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<h3>I'm a modal!</h3>
<ul>
<li ng-repeat="item in items">
<a ng-click="selected.item = item">{{ item }}</a>
</li>
</ul>
<p>Selected: <b>{{ selected.item }}</b></p>
<button class="button" ng-click="ok()">OK</button>
<a class="close-reveal-modal" ng-click="cancel()">×</a>
</script>
<button class="button" ng-click="open()">Open me!</button>
<div ng-show="selected">Selection from a modal: {{ selected }}</div>
</div>
</div>
</div>
use oclazyload
function nameOpen(name){
$ocLazyLoad.load('modal/name.ctrl.js').then(function(){
var modalInstance = $modal.open({
templateUrl: 'modal/name.html',
controller: 'nameCtrl',
controllerAs: 'vm',
resolve: {
phones: function () {
return name;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
//$log.info('Modal dismissed at: ' + new Date());
});
});
}