I'm using AngularJS translate, and If I use it as says the tutorial from pascalprecht my angular app fail and it doesn't show anything (it doesn't load partial views), so I decided to use angular-translate-partial-loader
I have one app menu, and I have a MenuCtrl to display options, I want to translate this menu
Here Is my code
angular.module('myapp'['ngAnimate','ngAria','ngCookies','ngMessages','ngResource','ngRoute','ngSanitize', 'ngTouch', 'pascalprecht.translate'])
.value('language', 'bra')
.run(function ($rootScope, $translate)
{
$rootScope.$on('$translatePartialLoaderStructureChanged', function ()
{
$translate.refresh();
}
);
})
.config(function($translateProvider, $translatePartialLoaderProvider) {
$translateProvider.useLoader('$translatePartialLoader', {
urlTemplate: 'translations/{lang}/{part}.json'
});
$translateProvider.preferredLanguage("bra");
})
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.when('/about', {
templateUrl: 'views/about.html',
controller: 'AboutCtrl'
})
.otherwise({
redirectTo: '/'
});
});
angular.module('myapp')
.controller('MenuCtrl', function ($scope, $translatePartialLoader) {
$translatePartialLoader.addPart('menu');
$scope.lItems = [
{
title: "HOME",
class:'active',
href:'/',
visible: true
},
{
title: "CLASSROOMS",
class:'',
href:'#',
visible: true
},
{
title: "EXPENSES",
class:'',
href:'#',
visible: true
},
{
title: "EARNINGS",
class:'',
href:'#',
visible: true
},
{
title: "STUDENTS",
class:'',
href:'#',
visible: true
}
];
});
In index.html
<div id="navbar" class="navbar-collapse collapse" ng-controller="MenuCtrl">
<ul class="nav navbar-nav" ng-repeat="lItem in lItems">
<li class="{{lItem.class}}">{{lItem.title | translate}}</li>
</ul>
</div>
Can you help me?
Thanks!
Finally I found the solution.
The trouble was that the menu is out of ng-view block, and when the app loads doesn't refresh the correct html part.
By adding this $translatePartialLoaderProvider.addPart('menu');
.config(function ($translateProvider, $translatePartialLoaderProvider) {
$translatePartialLoaderProvider.addPart('menu');
$translateProvider.useLoader('$translatePartialLoader', {
urlTemplate: 'translations/{lang}/{part}.json'
});
$translateProvider.preferredLanguage('bra');
....
When the application loads the menu part is also loaded.
Related
I'm a begginer with angular 1.6 and I would like to do the next:
Loggin, register & remember password without menu.
After loggin: Menu, nav bar and footer appears.
Up to now I have the next:
Index.html
<ui-view></ui-view>
Loggin: Works fine.
authenticationService.Login(vm.email, vm.password, function (result) {
if (result === true) {
$location.path('/main');
} else {
vm.error = 'Username or password is incorrect.';
vm.loading = false;
}
});
};
If I have logged I go to main, here my problems appear..
<!-- Wrapper-->
<div id="wrapper">
<!-- Navigation -->
<div ng-include="'../views/partials/main-navigation.html'"></div>
<!-- Page wraper -->
<div id="page-wrapper">
<!-- Topnavbar -->
<div ng-include="'../views/partials/main-topnavbar.html'"></div>
hola mundo
<!-- Main view -->
<div ui-view>aqui tengo que meter todas las vistas</div>
<!-- Footer -->
<div ng-include="'../views/partials/main-footer.html'"></div>
</div>
<!-- End page wrapper-->
Now I would like to put the rest of my web pages inside the main
<div ui-view>All pages here</div>
How Can I do this?
I have read several pages https://ui-router.github.io/ and some more, but It is not clear for me.
I think I have to do some in my app.js but I don't now what...
(function () {
'use strict';
angular.module('frontEndApp', [
'ui.router',
'ngMessages',
'ngStorage',
'ngAnimate',
'ngAria',
'ngCookies',
'ngMessages',
'ngResource',
'ngRoute',
'ngSanitize',
'ngTouch',
'ngStorage',
'ngResource',
'pascalprecht.translate']).config(config).run(run);
function config ($stateProvider, $translateProvider, $urlRouterProvider) { // default route
$urlRouterProvider.otherwise('/login');// app routes
var states = [
{ name: 'main', url: '/main', templateUrl: 'views/main/main.html' },
{ name: 'login', url: '/login', templateUrl: 'views/login/login.html', controller: 'loginController', controllerAs: 'vm' },
{ name: 'department', url: '/department', templateUrl: 'views/department/department.html', controller: 'departmentController', controllerAs: 'vm' }
];
// Loop over the state definitions and register them
states.forEach(function (state) {
$stateProvider.state(state);
});
/**
* Translation of the web page with angular-Translate
*/
$translateProvider.useStaticFilesLoader({
files: [{
prefix: '../config/languages/locale-',
suffix: '.json'
}]
});
$translateProvider.preferredLanguage('en');
$translateProvider.useSanitizeValueStrategy('escapeParameters');
}
function run ($rootScope, $http, $location, $localStorage) { // keep user logged in after page refresh
if ($localStorage.currentUser) {
$http.defaults.headers.common.Authorization = 'Bearer ' + $localStorage.currentUser.token;
}
// redirect to login page if not logged in and trying to access a restricted page
$rootScope.$on('$locationChangeStart', function (event, next, current) {
var publicPages = ['/login'];
var restrictedPage = publicPages.indexOf($location.path()) === -1;
if (restrictedPage && !$localStorage.currentUser) {
$location.path('/login');
}
});
}
})();
Thanks in advance for your help.
Simply:
{ name: 'main', url: '/main', templateUrl: 'views/main/main.html' },
{ name: 'login', url: '/login', templateUrl: 'views/login/login.html',
controller: 'loginController', controllerAs: 'vm' },
{ name: 'main.department', url: '/department', templateUrl:
'views/department/department.html', controller: 'departmentController',
controllerAs: 'vm' }
If department belongs to main then call it: 'main.department'
I've a very strange problem, it apparently seems that simple views template are preventing a controller to be executed, I can't understand why.
I've built a simple plunker
Code is here:
angular.module('plunker', ["ui.router"])
.config(function($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider.otherwise("/nested");
$stateProvider
.state('nested', {
url: '/nested',
controller: function($scope) {
$scope.sayHi = 'Hi';
this.sayHello = 'Hello';
},
controllerAs: 'dog',
//If I comment the "views" section, controller runs correctly
views: {
'main': {
template: 'MainContent'
},
'secondary': {
template: 'SecondaryContent'
}
}
})
$locationProvider.html5Mode(false).hashPrefix('!');
})
html:
<div ui-view>
<h1>{{dog.sayHello}}</h1>
<h1>{{sayHi}}</h1>
<p>Why no "hello" or "Hi" over here?</p>
<div ui-view="main"></div>
<div ui-view="secondary"></div>
</div>
If I comment out the "views" section in the state definition, controller runs correctly.
[edit]
Thanks to Radim, I resolved moving the controller definition in the views section:
views:{
'':{
controller: function ($scope) {
this.page = 'ten';
},
controllerAs:'dog'
},
'main#nested':{
template:'MainContent'
},
'secondary#nested':{
template:'SecondaryContent'
}
}
Check:
UI-Router Multiple Views Single Controller not work
The controller always belongs to view, not to state.
There is an updated plunker
.state('nested', {
url: '/nested',
//controller: function($scope) {
// $scope.sayHi = 'Hi';
// this.sayHello = 'Hello';
//},
//controllerAs: 'dog',
//If I comment the "views" section, controller runs correctly
views: {
'main': {
//template: 'MainContent', - let's use view, to consume dog.sayHello
templateUrl: 'view2.html',
controller: function($scope) {
$scope.sayHi = 'Hi';
this.sayHello = 'Hello';
},
controllerAs: 'dog',
},
'secondary': {
template: 'SecondaryContent',
controller: ...
}
}
check the updated plunekr
I'm learning angular, and have been trying to dynamically load a HTML file fragment into the content pane of a tab.
In this linked plunker I have created an angular module to configure the states
var app = angular.module('Plunker', ['ui.router', 'ui.bootstrap'])
app.config([
'$stateProvider',
'$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state("tab1", { url: "/tab1", templateUrl: "tab1.html" })
.state("tab2", { url: "/tab2", templateUrl: "tab2.html" })
.state("tab3", { url: "/tab3", templateUrl: "tab3.html" });
$urlRouterProvider.otherwise('/');
}]);
app.controller("tabsController", function ($rootScope, $scope, $state) {
$scope.tabs = [
{ title: "My Tab 1", route: "tab1", active: true },
{ title: "My Tab 2", route: "tab2", active: false },
{ title: "My Tab 3", route: "tab3", active: false },
];
$scope.go = function (route) {
$state.go(route);
};
$scope.active = function (route) {
return $state.is(route);
};
$scope.$on("$stateChangeSuccess", function () {
$scope.tabs.forEach(function (tab) {
tab.active = $scope.active(tab.route);
});
});
});
and in the index.html body assign the ui-view a name to associate it with the state/route
<body ng-app="Plunker">
<div ng-controller="tabsController">
<uib-tabset>
<uib-tab ng-repeat="tab in tabs" heading="{{tab.title}}" active="tab.active" disable="tab.disabled">
<div ui-view="{{tab.route}}"></div>
</uib-tab>
</uib-tabset>
</div>
</body>
Each tab should have content coming from the respective html file fragment tab1.html, tab2.html or tab1.html. But I cant get it to work. Any help making this work would be much appreciated.
You want to have one partial for each tab. For that, the named views feature of ui-router can help you. You won't change state, but having the content on dedicated views allows you to keep the parent template light and nicely organize your code. Moreover you could reuse the tab templates elsewhere.
State definition where the tabset component resides:
$stateProvider
.state('example', {
url: '/example',
views: {
"tab1": { templateUrl: "tab1.html" },
"tab2": { templateUrl: "tab2.html" },
"tab3": { templateUrl: "tab3.html" },
}
Tabset definition:
<uib-tabset>
<uib-tab ng-repeat="tab in tabs" heading="{{tab.title}}" ...>
<div ui-view="{{tab.route}}"></div> <!-- ex: <div ui-view="tab1"></div> -->
</uib-tab>
</uib-tabset>
See updated plunker
I would to make something like this:
.state('tabs.order', {
url: "/order/:orderId",
views: {
'orders-tab': {
templateUrl: "templates/orderDetail.html",
controller: 'OrderDetailController'
},
'orders-all-tab': {
templateUrl: "templates/orderDetail.html",
controller: 'OrderDetailController'
}
}
})
then in my view i would to put a conditional ui-sref in which i can choose the tab to be addressed; something like this:
ui-sref="tabs.order({orderId:order.ID}, <orders-tab or orders-all-tab?>)"
would this be possible?
Thanks
Well, I don't think there is any way yet to specify the view in ui-sref, but here is a starting point which I hope it will help you..
Firstly, the routes:
app.config(function($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise("/order/all-orders");
$stateProvider
.state("order", { abtract: true, url:"/order", templateUrl:"main.html" })
.state("order.orderTab", { url: "/order-details", templateUrl: "orderDetails.html" })
.state("order.orderAllTab", { url: "/all-orders", templateUrl: "allOrders.html" });
});
Then, define your main page (Orders and Order Details) [main.html]
<div ng-controller="mainController">
<tabset>
<tab
ng-repeat="t in tabs"
heading="{{t.heading}}"
select="go(t.route)"
active="t.active">
</tab>
</tabset>
<h2>View:</h2>
<div ui-view></div>
</div>
And the page controller to specify the tab data:
app.controller("mainController", function($rootScope, $scope, $state) {
$scope.go = function(route){
$state.go(route);
};
$scope.active = function(route){
return $state.is(route);
};
$scope.tabs = [
{ heading: "Order", route:"order.orderTab", active:true },
{ heading: "All Orders", route:"order.orderAllTab", active:false },
];
$scope.$on("$stateChangeSuccess", function() {
$scope.tabs.forEach(function(tab) {
tab.active = $scope.active(tab.route);
});
});
});
All you have to do next is to include the orderID.
Here is a demo
Trying to show hide menus based on user login using a custom directive. It all works fine in the views templates but in header it does not work [header is a different template]. It works fine on page refresh though.
header.html
<div id="header" class="navbar">
<a class="navbar-brand" href="#">My APP</a>
<ul class="nav nav-pills">
<li has-logged="!in">Sign Up</li>
<li has-logged="in">Home</li>
</ul>
</div>
has-logged directive
angular.module('myApp')
.directive('hasLogged', function(CookieService) {
return {
link: function(scope, element, attrs) {
if(!_.isString(attrs.hasLogged))
throw "hasLogged value must be a string";
var value = attrs.hasLogged.trim();
var notLoggedFlag = value[0] === '!';
if(notLoggedFlag) {
value = value.slice(1).trim();
}
function toggleVisibilityBasedOnLogin() {
var logged = CookieService.getLoginStatus();
if(logged && !notLoggedFlag || !logged && notLoggedFlag)
element.show();
else
element.hide();
}
toggleVisibilityBasedOnLogin();
}
};
});
app.js config
var myApp = angular.module('myApp',['ngRoute','ngCookies']);
myApp.config(function ($routeProvider,$httpProvider) {
$routeProvider
.when('/', {
templateUrl: 'app/module/public/index.html',
header: 'app/partials/header.html',
footer: 'app/partials/footer.html'
})
.when('/login', {
templateUrl: 'app/module/login/login.html',
header: 'app/partials/header.html',
footer: 'app/partials/footer.html'
})
.when('/home', {
templateUrl: 'app/module/home/home.html',
header: 'app/partials/header.html',
footer: 'app/partials/footer.html'
})
.when('/register', {
templateUrl: 'app/module/register/register.html',
header: 'app/partials/header.html',
footer: 'app/partials/footer.html'
})
.otherwise({redirectTo: '/'});
});
Code to add header and footer on app run
// Adds Header and Footer on route change success
$rootScope.$on('$routeChangeSuccess', function (ev, current, prev) {
$rootScope.flexyLayout = function(partialName) { return current.$$route[partialName] };
});
I tried this POST solution but still the same effect.
How do i change the menus without page refresh??
You may look into ui-router. It supports multiple and nested views.
Demo Fiddle
Click on First and Second to navigate between both states.
Here is the basic setup
First you need the views:
<div ui-view="header"></div>
<div ui-view="content"></div>
<div ui-view="footer"></div>
Then some sort of navigation to switch between ui states:
<ul>
<li>First</li>
<li>Second</li>
</ul>
Here is a basic state configuration:
myApp.config(function($stateProvider, $urlRouterProvider) {
// default route
$urlRouterProvider.otherwise("/first");
// ui router states
$stateProvider
.state('first', {
url: "/first",
views: {
header: {
template: '<h1>First header</h1>',
controller: function($scope) {}
},
content: {
template: '<p>First content</>',
controller: function($scope) {}
},
footer: {
template: '<div>First footer</div>',
controller: function($scope) {}
}
}
})
.state('second', {
url: "/second",
views: {
header: {
template: '<h1>Second header</h1>',
controller: function($scope) {}
},
content: {
template: '<p>Second content</>',
controller: function($scope) {}
},
footer: {
template: '<div>Second footer</div>',
controller: function($scope) {}
}
}
});
});