I have an app where the entire routing is handled by the angular app. For instance I have many angular routes such as the following:
$routeProvider
.when("/users",{ controller: "userController", templateUrl: "partials/users.html" })
and on the back end app I have
router.get('/partials/:name', function(req, res, next) {
var name = req.params.name;
res.render('admin/partials/' + name);
});
This set-up also uses the ugly localhost/#/ hack. I want to switch all routing to Express and get rid of this hack in the process. What options do I have, in terms of least amount of files that will need to be modified.
Basically I want to return full rendered HTML with dynamic data generated from API routes for that particular endpoint integrated with it (possibly with the use of an HTML preprocessor such as Jade), and stop using Angular's to render templates and then embed API data to it.
What options do I have, in terms of least amount of files that will need to be modified.
is hard to decide without knowing your code and it's dependencies.
But I would suggest to have a closer look at jade conditionals, jade includes and jade extends. I use the jade preprocessor from within express apps to prepare jade templates and are very satisfied with that solution.
If you generate HTML-pages without any further dynamic content consider to use express' static feature.
If you have to do some very special processing of jades output you can do it within the callback before storing/delivering the file.
A snipped:
jade.compile('./templates/jade/remotecontrol.jade',
{title:'Remotecontrol',
copt:customoptions,
key:project.key,
objects:JSON.stringify(project.objects),
buttons:{login:true},
controls:{joystick:true},
forms:{login:true}},
{callback:storeTo,
storeTo:__dirname+'/projects/'+project.key+'/stk/index.html',
pretty:true})
For a template like (please recognize the "include ../../../" as the path has to be relative from the template, not the node app)
doctype html
html(lang="de")
head
title #{title}
meta(charset="UTF-8")
include ../../../templates/jade/favicon.jade
meta(name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no")
link(rel="stylesheet" type="text/css" href="styles/client.css")
script.
var objectsToInject=!{objects};
var key='#{key}';
...
body
include ../../../templates/jade/loading.jade
div.bodycontainer()
button.beforebgr(name="fullscreen" id="fullscreen" class="fullscreen") Fullscreen
if controls.joystick
div.draggable(id="divjoystick" class="draggable ui-widget-content")
include ../../../templates/jade/joystickbase-svg.jade
include ../../../templates/jade/joystick-svg.jade
...
- var scriptname="'libs/js/remotecontrol.js'"
include ../../../templates/jade/loadscript.jade
Related
This is a generic question don't need the "ready to use" code , but an idea where should invest my time in. I set mustache tag because may be similar.
This is an express (4) application using .doT template where i want to expand with some angular (1.4.3) features.
Doesn't seem possible to me to work with .doT template and angularjs , I'm i right here? .I'm trying get it to work a .html template file and his angular application without success( return a 404 cause don't find a template, but when i use with ejs, it does work ( because it read .html files)
2 . STILL , would like to know in case i'm wrong above. considering this anwer that state is possible to use multiple view engine with consolidate. is possible and how would it be done with angular? (just a hint, doens't need to be the whole implementation)
I know by this answer would be possible to use this below, but also says is better to use a helper, is possible to use helpers in.doT template ? , how?
appModule.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
});
considering the above. Which one of 2 and 3 whould you say would be faster?
it would considerably be faster if I change my app to ejs view engine ?
Point by point :
This is incorrect , .doT template works well with Angular, I have use it both, as long as you render a route with dot.
router.get("/blog/new", function(req, res) {
res.render("owner/blog/create");
});
and set a state in your angular provider like
$stateProvider
...
.state("owner-new-blog", {
url: "/blog/new",
templateUrl: "/owner/blog/new",
controller: "CreateUpdateCtrl"
})
There is no point to use consolidate middleware, .doT template works with angular template out of the box, unless you change .doT default parameters.
Yes ... that would be like this , like state in this post
var dT = require('doT');
var tpl = {
tmpl:dT.template('{{=this.helper()}}'),
helper: function(){
/* do what you want to do */
}
}
tpl.tmpl(); // render template
as you can see in this benchmark , .doT is pretty fast if you set double engine in you app , is a bit slowe since you are expanded is functionallity, if you set a helper in doT is less painfull than having two engines .. so , is faster adding a Helper to dot.
there is no point in changing to ejs , dot is pretty fast and an advance template engines which suport layouts and partials. and still , in my opinion, is faster.
I am trying to create a nice dynamic theming system in my angular app.
Basically I have a Wordpress plugin which you pick via a dropdown which theme you want for my Angular app (which is on the same server in a subfolder), and I pass along the theme via a GET param, www.mywebsite.com/myapp/welcome?theme=white_theme, and the angular app in that folder currently will quickly set in the frontcontroller (think I will move this into an app.js resolve for the route so it happens before the controller, right now I just have the resolve setting a default theme):
var dynamic_theme = URI.parseQuery(query_string).theme; //url param gotten via URI js library
if(dynamic_theme) {
$rootScope.theme_name = dynamic_theme;
} else {
$rootScope.theme_name = 'default';
}
and later on in the index.html i include the dynamic theme via ng-href:
<!-- build:css(.tmp) styles/generic.css -->
<link rel="stylesheet" href="styles/generic.css">
<!-- endbuild -->
<link rel="stylesheet" ng-if="theme_name" ng-href="styles/themes/{{theme_name}}/main-theme.css">
But I also want the .html templates themselves to be able to be overwritten by our design theme for each theme.
For example, in app.js, to start off this 'questionnaire' app I have this defined:
templateUrl: 'views/main.html',
and in that file, i have a directive:
That directive uses the template 'views/question.html'
which inside of that file I decide whether to get 'views/templates/radio.tpl.html', 'views/templates/checkbox.tpl.html', 'views/templates/dropdown.tpl.html' based on the question-type passed to the directive.
like so:
<div ng-include src="'views/templates/' + currentquestion.question_type + '.tpl.html'"></div>
I guess maybe I can pass the theme into the directive (or just have access to the $rootScope) and do something like so:
<div ng-include src="'views/templates/' + dynamic_theme + '/' + currentquestion.question_type + '.tpl.html'"></div>
I was just curious if that sounds like a plan. or is there a better way to do this (or even a real theming resolver library/setup you can use for Angular that does the same things that I'm trying to achieve manually).
There seem to be a number of different ways to do this, the most promising looks to be using templateUrl as a function:
templateUrl: function(elem,attrs){
return 'views/templates/' + resolveTheme() + 'main.tpl.html';
},
You would have to write resolveTheme() yourself, possibly as a global or a service.
Alternative
Another option, if you can precompile your templates you can use the $templateCache and dynamically load the right template pack. You'd need to make sure this happened before any of the templates were requested as angular will make an HTTP request for any templates that it can't already find.
Here is one way to pre-compile your templates:
https://github.com/karlgoldstein/grunt-html2js
You could then have multiple template packs: template-theme1.js, template-theme2.js
And either build multiple versions of the app or include these templates after your application code (but before any templates get requested).
I'm trying to use the RouteProvider functionality in Angular. A different partial html template should be loaded depending on whether the user is editing a form, viewing a list of completed entries, etc. I've been unable to load the html templates within the same page. Instead, the user is redirected to a different page.
Here's the relevant Angular code:
.when(/new', {
controller: 'CreateCtrl'
templateUrl: 'partials/newform.html'
The Laravel Route:
Route::resource('services', 'ServicesController');
The newform.html file is located at resources/views/partials/newform.html within Laravel.
Any thoughts on how I can load these partial html templates from Laravel?
One way would be to reference the full path to the partials
.when('/new', {
controller: 'CreateCtrl'
//depending on your path adjust it
templateUrl: 'partials/newform'
since you are just using .html not tempalte.blade.php file for template you should move it to public folder.
Update:
If you really dont want to move the template out of view folder of laravel
create a route and serve your html from there
Route::group(array('prefix' => 'partials'), function(){
Route::get('/newform', function()
{
return File::get(app_path().'Views/partials/angular.html');
});
});
Note: I will suggest you not to mix Laravelc template with Angular, keep Laravel as REST API, and your Angular should separate layer.
Here are some Pros and Cons for both approach
I found another way using gulp, i leave my solution :)
In gulpfile.js inside elixir function add this line:
var elixir = require('laravel-elixir');
elixir(function(mix) {
mix.copy('resources/assets/js/angular/components/**/*.template.html', public/angular-templates');
//Find all files with suffix .template.html
});
As you notice it, i created a folder called 'angular' and then another one called 'components', there we will have our components
Angular-----------------------------
--Components------------------------
----my-component.directive.js-------
----my-component.template.html------
We have to create a global angular variable taking our browser window origin (www.myapp.com, localhost:8000, etc) by doing:
angular.module('myModule',[])
.value('pathAssets', location.origin + '/angular-templates/')
In our templateUrl we will call the template by writting:
templateUrl: pathAssets + '../angular-templates/my-template.html',
I have to say we have to concat our angular files in a file, otherwise it won't work D: if you don't know how to do it, add these lines in your gulpfile.js
mix.scripts([
'../../../bower_components/angular/angular.min.js',
'angular/app.js',
'angular/controllers/**/*.controller.js',
'angular/components/**/*.directive.js',
'angular/bootstrap.js',
], 'public/js/app.js'); //We concatenate angular files saving them in app.js
Finally execute the command 'gulp' in terminal(In our project), it should generate a new folder in public called angular-templates.
CONCLUSION
1. Move all your angular templates to public inside a specific folder by using elixir.
2. create a global variable in angular to save your origin URL and use it in your directives it automatically with this template in public.
I have a webapp with a main index.html that shows each page through an ng-view and a routeProvider.
Now I'm adding an entry page for users who are still not logged in. This page could also have his own ng-view to slide different sections for non logged users (welcome, what is, sign in, sign up ecc...) and his own head with css scripts ecc...
I'd rather that both the webapp index and the entry page index address to www.example.com (so nothing like www.example.com/welcome ).
I thought about a structure similar to this:
webapp/
main/
page1/
page2/
welcome/
section1/
section2/
index.html
welcome.js (angular module for the entry page)
.htaccess
index.html
webapp.js (angular module containing the routeProvider for the webapp)
Currently I have that .htaccess that rewrites all the fake queries to index.html so that everything is handled here.
So in particular:
1) How can I say to the routerProvider of webapp.js to go to /welcome/index.html when the user is not logged in, if I already use this condition for the webapp main page? (Should I use the run method? a brief example will be helpful)
.config(['$routeProvider', function($routeProvider){
$routeProvider
.when(...)
.when('/', {
templateUrl : 'main/webapp-main.html'
})
.when(...)
2) How do I prevent that everything in welcome/index.html will be loaded within the index.html ng-view? (maybe using ng-if to hide ng-view? or there is some way to control this behavour with the routerProvider?)
3) There is a better and simpler way to achieve all of this?
Thanks.
Update:
Ok I think there was an underlying problem in my question... I can't use a complete different page since everything is loaded in and switching to another page will cause the reload of the app loosing all the data.
So I suppose I should use the same main template for the entire website.
Then I add: there is a way in angularjs to load different style sheets dynamically?
this questions is old but i think is valid and can clarify someone a few thinks.
First of all you are suppose to use a single page for AngularJS apps, otherwise you will have to do something like a redirect link, and in your other-index.html load an entirely different Angular Application also loading every script needed in the first one.
1) Use ui-router is easy to work, and very robust, the only thing you need to have is a container for your ui-view then the ui-router will fill the container with the corresponding html
2) To prevent navigation you should do something like this:
angular.module('myApp', [])
.run(function($rootScope, mySessionService){
$rootScope.$on('$stateChangeStart',
function(event, next, nextParams, prev, prevParams) {
// The info of your currentUser could be obtain from a service
// or localStorage or cookies anyway you are already doing it
var authorized= checkAuthorization(next.authorazedRoles,
mySessionService.getCurrentRol());
if(!authorized) {
$rootScope.$state.go('defaultState');
// Or $rootScope.$emit('NOT_AUTHENTICATED');
// and some service will have to implement a listener for this emit
// $rootScope.$on('NOT_AUTHENTICATED', func..redirect to X State)
}
});
});
I'm currently migrating from custom framework to Angular. Since we've got legacy, all front-end resources like stylescheets, images and scripts should be located on a subdomain, and all urls should be absolute. I've got a bunch of css files with a parameter specifying our static domain. I'm looking for a native Angular approach to using parameters in css, so I'll be able to write smth like:
.body {background: "{{domain}}/img/bg.png";}
Currently in our framework styles are loaded with, say, $http.get(), then processed with .replace and then appended to DOM.
Any ideas?
Thank you.
Try the $interpolate service. Inject it in a method, then use like this:
var fn = $interpolate(cssText);
var processedCssText = fn(scope); // scope is whatever obj that contains `domain` and other properties that might be used inside cssText
You can even configure the opening & closing symbols, if needed. See the documentation for $interpolate for more information.
You want LESS.
http://lesscss.org
It's the "dynamic stylesheet language".