.dot template and angular or what should I use here? - angularjs

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.

Related

AngularJs Change url generated using index of and routeparams

In the address bar of the browser the $routeProvider returns ".../index#/projects/0".
This is the view for that particular project. What I am trying to achieve is to either hide the indexOf value, in this case the "0" and have the url as ".../index#/projects/somethingelse". Linking to the project using <a href="#/projects/{{projects.indexOf(project)}}"> and "/projects/:id" in the $routeProvider config. I have tried certain methods but cannot get any results.
Say for example the the first project in the projects array is called, the url in the browser is "/projects/0". Is it possible to replace the 0 to have the url start at 1 but still return the values of the object in project array[0] and so on. Basically trying to find a rewrite method in the controller or service. Currently grasping AngularJS.
I have come accross this answer but don't know how to go about doing this to achieve what I need. Going by this answer I tried the following code in the controller $location.path($route.updateParams({id:"project"})); it does give the desired result: from ".../index#/projects/0" to "../index#/projects/project" but when navigated to the view, it is blank and the project details are not returned.
Also any good pointers, tutorials, books on URL rewrites and security in AngularJS? The AngularJs version I am using is 1.5.8.
You can use whatever you want in the route params, so long as you can link it to the right data.
If you want to offset the index by 1, simply use something like this (assuming projects is available / injectable)
.when('/projects/:id', {
resolve: {
project: function($routeParams, projects) {
return projects[$routeParams.id - 1];
}
},
// etc
To use an arbitrary property like id, try Array.prototype.find
resolve: {
project: function($routeParams, projects) {
return projects.find(project => project.id === $routeParams.id);
}
}
To create links, you'd use something like
<a ng-href="#/projects/{{projects.indexOf(project) + 1}}">
or
<a ng-href="#/projects/{{project.id}}">

Linking to external URL with different domain from within an angularJS partial

All I am trying to do is include an anchor tag inside the html of a partial that links to an external site. Were this standard html, the code would simply be:
google
As simple as this is, I cannot seem to find a working solution for getting past angular intercepting the route (or perhaps replacing my anchor with the https://docs.angularjs.org/api/ng/directive/a directive unintentionally?).
I have scoured SO and the rest of the web and seen a myriad of solutions for dealing with: links within the same domain, routing within the SPA, routing within a page (ala $anchorScroll) but none of these are my issue exactly.
I suspect it may having something to do with using $sce but I am an Angular n00b and not really sure how to properly use that service. I tried the following in my view controller:
$scope.trustUrl = function(url) {
return $sce.trustAsResourceUrl(url);
}
with the corresponding:
<a ng-href="{{ trustUrl(item) }}">Click me!</a>
(as described here: Binding external URL in angularjs template)
but that did not seem to do the trick (I ended up with just href="{{" in the rendered page).
Using a plain vanilla anchor link like this:
google
also failed to do the trick (even though some online advised that standard href would cause a complete page reload in angular: AngularJS - How can I do a redirect with a full page load?).
I also tried adding the target=_self" attribute but that seemed to have no effect either.
Do I need to write a custom directive as described here?
Conditionally add target="_blank" to links with Angular JS
This all seems way too complicated for such a simple action and I feel like I am missing something obvious in my n00bishness, at least I hope so because this process is feeling very onerous just to link to another url.
Thanks in advance for any solutions, advice, refs or direction.
It turns out that I did in fact have all anchor links in the page bound to an event listener and being overridden. Since that code was fundamental to the way the page worked I did not want to mess with it. Instead I bypassed it by using ng-click to call the new url as follows:
HTML:
<a class="navLinkHcp" href="{{hcpurl}}" title="Habitat Conservation Plan" target="_blank" ng-click="linkModelFunc(hcpurl)">Habitat Conservation Plan</a>
Controller:
$scope.hcpurl = 'http://eahcp.org/index.php/about_eahcp/covered_species';
$scope.linkModelFunc = function (url){
console.log('link model function');
$window.open(url);
}
And voila! Good to go.
Thanks again to KevinB for cluing me in that this was probably the issue.

AngularJS register controller once

That's what I'm doing. There is application with pages and different controls that may be put on pages by site admin/editor. All pages share one ng-app defined on master page. All controls are supplied with .js files with angular controllers. Let's suppose that I have an image gallery block:
<div ng-controller='imageGalleryCtrl'>
do something amazing here
</div>
<script src='imageGallery.js'></script>
Inside script there is a simple controller registration like:
angular.module('myApp').controller('imageGalleryCtrl', ... );
So. If I have 10 image galleries, I'll execute controller registration 10 times. It looks like this will work, but hell - I don't want it to be so =)
For now I just have all controls' scripts registration on a master page, but I don't like it as well, because if there is no image gallery on a page, I don't want it's script be downloaded during page load.
The question is - is there any proper way to understand if controller have been registered in a module already and thus prevent it from re-registering?
---------------
Well, though I've found no perfect solution, I must admit that the whole idea isn't very good and I won't think about it before my site will grow too big to assemble whole angular app on master page.
You should declare your controller but once. Instead of having one controller per gallery, have your single controller handle all image galleries. The controller should make a request to the REST backend to fetch the images of the desired gallery.
I see that instead of ng-view, you're using the ng-controller directive, indicating that probably you're not using Angular's routing. Try switching to using routes.
Have a look at Angular.js routing tutorial. It shows you how to use the ngRoute module. Then, in the next chapter, the use of $routeParams is described. Via the $routeParams service, you can easily say which gallery should be displayed by providing its ID in the URL; only one controller will be necessary for all your galleries.
If you really must check whether a given controller has been declared, you can iterate through the already declared controllers (and services... and pretty much everything else) by checking the array angular.module("myApp")._invokeQueue. The code would probably look something like this (not tested!):
var isRegistered = function(controllerName)
{
var i, j, queue = angular.module("myApp")._invokeQueue;
for (i = 0, j = queue.length; i < j; ++i) {
if (
queue[i][0] === "$controllerProvider"
&& queue[i][1] === "register"
&& queue[i][2][0] === controllerName
) {
return true;
}
}
return false;
};
Bear in mind however that while this may (or may not) work, it's far from being the correct thing to do. It's touching Angular's internal data that's not meant to be used in your code.

How can I dynamically set templates without messy query parameters in angular ui-router?

I'm building an artist portfolio web app where the artist can create a 'project' which consists of a series of content pieces (mostly images at this point) which can then be put in an order and the artist can choose between different preset layouts. I'm using angular and node + express. I'm struggling to find a good way to dynamically set templates. The only functional scheme i've devised so far is to put the template name in a query parameter in the url like this.
ui-sref="webapp/project/photo?template=vertical"
then in ui-router it's relatively simple to set the template using state params
templateUrl : function (stateparams) {
return 'templates/' + stateparams.template + '.html';
},
Although it's functional I don't like this mostly because it creates messy urls and allows anyone to change templates with query params or more likely load something without a real template because the url was typed incorrectly or correctly without the query parameter.
I can't make an api call from the templateUrl function because it's not injectable so I can't use the $http service. I've tried to use template provider but haven't made anything functional out of that yet. It does allow for an injectable function but that function must return an entire template instead of a url. If I can get a template url for it how can a load the template with that? I assume I'm not the first person to want dynamic templates (templates set in the database) from angular. What are my best options?
I have found a functional solution to my problem using ui-router, $stateParams, and $http. I'll be looking for a better architecture scheme as this necessitates 3 server requests every time a project is requested. One to get the template name and another to load the template file and another to load the project data. I suppose I only added one request to the norm. Anyways.. This solution is working for me but next I will be moving the logic to get template by the project name to an angular service to keep everything clean.
.state('projects/:project_url', {
url : '/projects/:project_url',
templateProvider : function ($stateParams, $http) {
return $http.get('/api/projects/' + $stateParams.project_url)
.then(function (data) {
// get template name
var templateName = data.data[0].template;
// return template by name
return $http.get('/pages/' + templateName + '.html')
.then(function (data) {
return data.data;
});
});
},
controller : 'projectCtrl'
});
http://dotjem.github.io/angular-routing/ supports your scenario with inject-able template functions. Note however that you must provide the raw template in the return statement, but that is easily done using the $template service...
It is very similar to UIRouter, so it should be a fairly easy transition if you find it worth it.
http://plnkr.co/edit/dkPIWMW236ixifETohNW?p=preview
If you take the latest stable release rather than the head you must add a "get" call to that service as: $template.get('template.html') rather than the newer: $template('template.html')

How to redirect in AngularJS without rendering template

I'm trying to redirect to an external page from my AngularJS file if the user enter a special url, for instance /test. I have gotten this to work in multiple different ways but all the different ways show a "flash" of the design from index.html. I would like it to go direct without rendering any html at all!
Here is a fiddle of one of the examples, but it is not the best place to test since I cant redirect from jsiffle.net :-)
$routeProvider.when("/test", {
resolve: {
controller: "Redirect"
}
});
Also had one example where I just used a controller and a empty template in the routing, but it gave me the same result.
Any ideas?
If you know the URL(routing) then use,
$location.path('the_URL');

Resources