I have started learning angularjs recently and I am doing some stuff. I tried to use this actice example, especially 3 example. I tried to read from tempate files by their url but I couldn't. I got bellow code (here only peace of code which I changed):
var app = angular.module('app', []);
app.value('MultiViewPaths',
{'/' : {
content : {
templateUrl : './templates/_header.html'
},
secondaryContent : {
templateUrl : './templates/_secondaryContent.html',
controller : 'ListUsersCtrl'
}
},
'/cats' : {
content: {
templateUrl : 'templates/_headerCats.html',
controller : 'ListCatsCtrl'
},
secondaryContent : {
templateUrl : 'templates/_secondaryContentCats.html',
controller : 'CatOfTheMinuteCtrl'
}
}
});
app.directive("ngMultiView", ['$rootScope', '$compile', '$controller', '$location', 'MultiViewPaths','$templateCache', function($rootScope, $compile, $controller, $location, MultiViewPaths, $templateCache){
var getTemplate = function(templateUrl) {
console.log(templateUrl)
var template = $templateCache.get(templateUrl);
console.log(template)
return template
}
return {
terminal: true,
priority: 400,
transclude: 'element',
compile : function(element, attr, linker){
return function(scope, $element, attr) {
var currentElement,
panel = attr.ngMultiView;
$rootScope.$on('$locationChangeSuccess', update);
update();
// update view
function update(evt, newUrl, oldUrl){
if(!newUrl){ return }
var url = newUrl.match(/#(\/.*)/),
match, template, controller;
match = url ? MultiViewPaths[url[1]] : MultiViewPaths['/'];
template = getTemplate(match[panel].templateUrl);
console.log(template)
controller = match[panel].controller;
if(template){
var newScope = scope.$new(),
locals = {},
newController = controller;
linker(newScope, function(clone){
clone.html(template);
$element.parent().append(clone);
if(currentElement){
currentElement.remove();
}
var link = $compile(clone.contents());
currentElement = clone;
if (newController) {
locals.$scope = newScope;
var controller = $controller(newController, locals);
clone.data('$ngControllerController', newController);
clone.children().data('$ngControllerController', newController);
}
link(newScope);
newScope.$emit('$viewContentLoaded');
});
}else{
//cleanup last view
}
}
}
}
}
}]);
Other thing the same with example. I could not read templates inner html. Can anyone help me ?
I would recommend using uiRouter rather than ngRouter. With uiRouter you do not need to create a directive to handle changing the view for different URL parameters.
They give an example of how to do this using the $stateProvider here http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$stateProvider
templateUrl: function(params) {
return myTemplates[params.pageId]; }
Related
I am trying to communicate between two directives. I tried the service way, it didn't work. Maybe I am doing something wrong.
<list-data testing="trial" template-url="grid.html" link-passed="data.json"></list-data>
My directive and service:
app.directive('listData', function($http, serVice){
return {
restrict: 'E',
scope: {
testing: '#',
linkPassed: '#'
},
templateUrl: function(elem,attrs) {
return attrs.templateUrl || 'some/path/default.html'
},
link: function($scope){
var url = 'js/' + $scope.linkPassed;
$http.get(url).then(success, error);
function success(data){
$scope.iconUrl = data.data;
}
function error(response){
console.log(response)
}
$scope.tryingToClick = function(icon){
serVice=icon.name;
console.log(serVice)
}
}
};
});
app.directive('render', function(serVice){
return {
restrict: 'E',
template: '{{rendering}}',
link: function($scope){
$scope.rendering = serVice.name;
console.log(serVice)
}
};
});
app.factory('serVice', function(){
return{items:{}};
})
grid.html is just a simple grid layout where I am trying to show the data in grid.
<div class="col-sm-6 grid" ng-repeat="icon in iconUrl">
<p ng-click="tryingToClick(icon)">{{icon.iconUrl}}</p>
</div>
I need to pass the data when I click the function tryingToClick and the icon passes to the render directive. I cannot use $rootscope here, nor make new controllers. I will be using the logic here in a pretty big enterprise app, just that I made a very simple version of it on my localhost, just to get the logic right.
Your service doesn't look quite right. I'd use
app.factory('serVice', function() {
var settings = {};
// optionally set any defaults here
//settings.name = 'me';
return settings;
});
and you're not setting the name property of the service here:
serVice=icon.name;
It should be
serVice.name = icon.name;
given that you're looking for the name property later: $scope.rendering = serVice.name;
What do you mean by not creating more controllers? Do you mean that you can't create more on the app or that you can't use controllers within the directives?
From what I understood of your question I threw this codepen together for experimentation http://codepen.io/ihinckle/pen/JWGpQj?editors=1010
<div ng-app="directiveShare">
<directive-a an-array="[1,2,3,4,5]"></directive-a>
<directive-b></directive-b>
</div>
angular.module('directiveShare', [])
.directive('directiveA', function(){
return {
restrict: 'E',
scope: {
anArray: '<'
},
controller: function($scope, aService){
$scope.clicked = aService.setIcon;
},
template: `
<ul>
<li ng-repeat="item in anArray" ng-click="clicked(item)">item</li>
</ul>`
}
})
.directive('directiveB', function(){
return {
controller: function($scope, aService){
$scope.displayIcon = aService.getIcon;
},
template: `
<h1>{{displayIcon()}}</h1>
`
}
})
.factory('aService', function(){
var srvc = {};
srvc.setIcon = function(x){
srvc.icon = x;
};
srvc.getIcon = function(){
if(srvc.icon){
return srvc.icon;
}else {
return '';
}
};
return srvc;
});
I used getters and setters in the service and controllers on the directives to expose the functions.
I have this directive, that i would like to make a component
angular.module('app')
.directive('year', function () {
var controller = ['$scope', function ($scope) {
$scope.setYear = function (val) {
$scope.selectedyear = val;
}
}];
return {
restrict: 'E',
controller: controller,
templateUrl: "views/year.html"
};
});
This is what I got so far:
angular.module('app')
.component('year', {
restrict: 'E',
controller: controller,
templateUrl: "views/year.html"
});
I am not sure how to move my var controller into .component
There are few things you should do convert your directive to component
There is no restrict property for component as it is restricted to elements only.
For controller you could just set as you did at directive declaration but outside of it.
Controllers for components use controllerAs syntax as default so get rid of $scope
So your component should look like this...
angular.module('app')
.component('year', {
controller: ComponentController,
templateUrl: "views/year.html"
});
function ComponentController(){
var $ctrl = this;
$ctrl.setYear = function (val) {
$ctrl.selectedyear = val;
}
}
Your component should look like this:
function YearController() {
var $ctrl = this;
$ctrl.setYear = function (val) {
$ctrl.selectedyear = val;
}
}
angular.module('app').component('year', {
templateUrl: 'views/year.html',
controller: YearController
});
For more details, please read the following Stack Overflow question for more deatils:
Angular 1.5 component vs. old directive - where is a link function?
and the official documentation:
https://docs.angularjs.org/guide/component
Also, please note that components are restricted to elements only by default.
I'm try to create dynamic framework with angularjs
here is my plan ... the user have to add the new templateUrl and controller from json file like this templates.json
{
"pages" : [
{
"name" : "home",
"tempUrls" : "views/home",
"controller" : "HomeController"
},
{
"name" : "about",
"tempUrls" : "views/about",
"controller" : "AboutController"
},
{
"name" : "contact",
"tempUrls" : "views/contact",
"controller" : "ContactController"
}
]
}
from here our job to create for hem the controller and templateUrl with the page name in angularjs like this hours.js
var hours = angular.module('hours', ['ngRoute']);
var $routeProviderReference;
var currentRoute;
hours.config(function($routeProvider){
$routeProviderReference = $routeProvider;
})
.run(['$route', '$http', '$rootScope', function($route, $http, $rootScope){
$http.get("templates.json").success(function(data){
var loop = 0, currentRoute;
for(loop = 0; loop < data.pages.length; loop++){
currentRoute = data.pages[loop];
var routeName = "/" + currentRoute.name;
$routeProviderReference.when(routeName, {
templateUrl: currentRoute.tempUrls,
controller : currentRoute.controller,
resolve: {
param: function()
{
return currentRoute.resolve;
}
}
});
}
$route.reload();
});
}]);
hours.controller(currentRoute.controller, function($scope){
$scope.pageClass = 'page-' + currentRoute.name;
});
and here is the index.html
<div ng-class="{{pageClass}}" ng-view></div>
and here is the static version from angularJS before i converted to dynamic
var hours = angular.module('hours', ['ngRoute']);
hours.config(function($routeProvider){
$routeProvider
.when('/', {
templateUrl: 'views/page-home.html',
controller: 'homeController'
})
});
hours.controller('homeController', function($scope){
$scope.pageClass = 'page-home';
});
i hope really someone can help!!!
This is how I am used to working with ng-class. It does appear to have multiple formats. This style requires single curly braces.
ng-class="{ myClass: ExpressionThatResolvesTrueOrFalse }"
So if the expression resolves true, then Angular will add myClass to the element. If it resolves false, it will not add the class. It will watch the value of the expression for changes as part of the normal scope digest.
I believe the model format does not use braces at all and is more like:
ng-class="pageClass"
I would like to know how attach css and templates url in a angularjs directive.
For example, with templates i have this
/*** myDirectives ***/
angular.module('myDirectives', [])
.directive('webcams', function($sce, $http, $templateCache, $compile) {
return {
restrict: 'A',
template: '<div class="included" ng-include src="getTemplateUrl();"></div>',
scope: {
stream_webcam: '=webcam',
stream_type: '#type'
},
controller: function($scope, $sce) {
$scope.getTemplateUrl = function() {
var url;
if ($scope.stream_webcam.webcam_domain == 'twitcam') {
url = 'templates/' + $scope.stream_webcam.webcam_domain + '.php';
} else if ... {
url = 'templates/second.html';
} else ...
return url;
}
...
How to put templates in my angularjs folder directive ?
Pass HTML template file to directive
you can pass by templateUrl . you can give CSS file link in your html file itself as usual.
app.directive('contactTable', ['$window',,
function($window) {
return {
scope: {
contact: "=",
},
restrict: 'A',
controller: 'contactTableController',
templateUrl: **your folder**+ '/contact-table-template.html',
link : function ($scope, element, attrs){
//your logic and dom access goes here
});
}
};
}
]);
I found several similar questions, however none of the answers helped. They all seem to involve some type of $location dependencies that I'm unable to get injected right.
My code below:
(function() {
// App dependencies
var app = angular.module('portalExchange',
['ngRoute',
'app-products',
'app-manage',
'app-profile']);
// [ Main Controller ] : PortalController
app.controller('PortalController', function($scope) {
if ($('.top_link_dashboard').hasClass('unactive_top')) {
$('.top_link_dashboard').removeClass('unactive_top');
$('.top_link_dashboard').addClass('active_top');
}
});
// Controller for Dashboard
app.controller('DashboardController', function() {
});
// Controller for Developers
app.controller('DevelopersController', function($scope) {
// Page.setTitle('Developers');
});
// Controller for Quote
app.controller('QuoteController', function($scope) {
// Page.setTitle('Begin Quote');
});
// Directive for Header
app.directive('appHeader', function () {
// Type of Directive, E for element, A for Attribute
// url of a template
return {
restrict: 'E',
templateUrl: 'templates/modules/globals/app-header.html'
};
});
// Directive for Footer
app.directive('appFooter', function () {
return {
restrict: 'E',
templateUrl: 'templates/modules/globals/app-footer.html',
controller: function(){
this.date = Date.now();
},
controllerAs:'footer'
};
});
// configure our routes
app.config(function($routeProvider) {
$routeProvider
// route for the dashboard page
.when('/', {
templateUrl : 'templates/sections/app-dashboard.html',
controller : 'DashboardController'
})
// route for the dashboard page
.when('/dashboard', {
title : 'My Dashboard',
templateUrl : 'templates/sections/app-dashboard.html',
controller : 'DashboardController'
})
// route : Developers Page
.when('/developers', {
title : 'For Developers',
templateUrl : 'templates/sections/app-developers.html',
controller : 'DevelopersController'
})
// route : Begin Quote
.when('/quote', {
title : 'Begin Quote',
templateUrl : 'templates/sections/app-quote.html',
controller : 'QuoteController'
});
});
app.run(['$rootScope', '$route', function($rootScope) {
$rootScope.$on('$routeChangeSuccess', function(newVal, oldVal) {
if (oldVal !== newVal) {
document.title = $route.current.title;
}
});
}]);
})();
The RUN function
app.run(['$rootScope', '$route', function($rootScope) {
$rootScope.$on('$routeChangeSuccess', function(newVal, oldVal) {
if (oldVal !== newVal) {
document.title = $route.current.title;
}
});
}]);
HTML
<!DOCTYPE html>
<html lang="en" ng-app="portalExchange" ng-controller="PortalController as portal">
<head>
<meta charset="utf-8">
<title ng-bind="title">myApp</title>
</head>
The way I do it is quite simple. In route configuration you define title:
.when('/dashboard', {
title : 'My Dashboard',
templateUrl : 'templates/sections/app-dashboard.html',
controller : 'DashboardController'
})
then you listen $routeChangeSuccess event and just set document.title. In application run block (the best place for this):
app.run(['$rootScope', '$route', function($rootScope, $route) {
$rootScope.$on('$routeChangeSuccess', function() {
document.title = $route.current.title;
});
}]);
The benefit of this approach is that it allows you to avoid one more binding ng-bind="title", which is good.
This is another way
app.run(['$rootScope', function($rootScope) {
$rootScope.$on('$routeChangeSuccess', function(_, current) {
document.title = current.$$route.title;
});
}]);
Because sometimes $route injection causes problem (for example, in running unit tests).
This is a little of topic, but I was trying to manage the page title in an angular application that uses ui-router and I ran into a couple of issues. First, of course, I had to change route and $routeChangeSuccess to $state and $stateChangeSuccess and second, I had an issue with the page title getting updated before the browser could add the previous page title to the history, so I had to add a timeout to the event handler resulting the following code:
angular.module('myApp').run(appRunFunction);
appRunFunction.$inject = ['$rootScope', '$state', '$timeout'];
function appRunFunction($rootScope, $state, $timeout) {
$rootScope.$on('$stateChangeSuccess', function() {
$timeout(function() { document.title = $state.current.title; }, 100);
});
}