Require.js Backbone modular architecture for r.js - backbone.js

my_todo_app.html has
todo_header.html
todo_body.html
todo_footer.html
The htmls above are rendered server-side.
todo_header.html creates HeaderView like below(and the two other htmls create their corresponding Backbone Views as well)
<div id='header-view'>
.. other html contents that are rendered in server-side
</div>
require([header_view], function(HeaderView) {
var headerView = new HeaderView({el: "#header-view");
});
Is this bad practice?
I'd like to concatenate javascript files for the todo app using r.js and stuck.
Because r.js concatenates files by looking at the dependancy, and I don't have a file that states todo app depends on HeaderView/BodyView/FooterView.
Should I not separate server-side htmls at all?

I just pluck out the javascript require call from nested-template.

Related

AngularJS preload pages (off line mode)

I would like to preload templates in AngularJS (with ng-route) so that when I am on the home page, after loading all the necessaries element, I can download some sub-pages of my application in order to, if the user lost connexion, he is still able to go on that page, without an internet connexion.
I tried to make different asynchronous calls on my pages but I'm not getting anywhere.
I hope it's clear
There are two approaches for this:
The first one is to use an Ajax call and get the HTML for your Sites and load it into the template Cache by yourself:
$http.get('./template.en.html').then(function (result) {
//put template into cache
$templateCache.put('myTemplateName', result.data);
});
The second would be to use OcLazyLoad:
$ocLazyLoad.load([
'path/to/template.html'
]);
But with this approach your Template files need to look like this:
<script type="text/ng-template" id="myTemplateName">
Content of the template.
</script>
Also you could load your controller files with ocLazyLoad

Scripts multiplies in controllers

I'am using node.js with sails.js for backend and angular.js for frontend.
In angular i am using one main controller and some childs conrtoller.
As you know, by default in sails.js, in file layout.ejs included all java scripts and css files between tags
<!--SCRIPTS--><!--SCRIPTS END-->
and
<!--STYLES--><!--STYLES END-->
Main content are included to <%- body %> tag
When i am lifted sails, go to browser and inspect "elements" i see some problem:
main controller (let it be "myApp") in angular generating html by using layout.ejs like main body (with all css and js), and then included controllers content.
Now problem:
Problem is that another child controllers of "myApp" generating by using layout.ejs too. And thats why some scripts included multiple times.
Example: 4 child controllers = 4 included of google.maps.api. Thats bad!! code so dirty!
And now question: how i can fix this issue, and make scripts and css included just one time?
Create another layout let's call it views/blanklayout.ejs with just this content:
<%- body %>
Now, use this layout with all child controller views.
Do either
In your sails controller set layout to blanklayout: res.locals.layout = 'blanklayout';
OR you can also specify layout in routes e.g.
'GET /test': {
controller: 'TestController',
action: 'test',
locals: {
layout: 'blanklayout',
},
},
PS: You can swap layouts also, meaning have just <%- body %> in layout.ejs and another layout (e.g. mainLayout.ejs to contain present content of layout.ejs. That way you'll not have to specify to use mainLayout only for main controller view.

Switch template routing to Express from Angular app

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

#section syntax instead of requirejs or browserify for angularjs application

I understand that requirejs and browserify can load my files dependent on its current context, and that it is amazing. I would really prefer to use the #section sections syntax that the razor engine uses. Was just wondering if there is a way to implement this into a typescript / angularjs application.
for example
index.html
#renderSection scripts;
// which could turn into something like
<script data-render="scripts"></scripts>
// the app.run() could declare all the scripts that will be needed on every
// page view
view.html
<script ng-section-repeat="injected in injection"></script>
// the ng-section-repeat is basically taking all the items in the
// typescript constructor and then finding out which ones are needed for
// that view.
I like the idea injecting application file dependencies in the view , without a configuration file and all the added extras that comes with the loaders.
I just want to easily define what files are needed in the actual view and get them loaded, with angular's dependency injection handling the dependency itself.
If you are handling all your dependencies with $inject then , as far as i can tell, dependency is technically already setup in the controllers, all one would need, is to load this as it is called. Which could even eliminate the need for the #section scripts completely
Update:
What i have done to sort of replicate the module loaders is to just use gulp-concat and define the file order in my gulp.config.js and then pass it to the gulp-src before running $.concat .this allows me to have the files in the gulp steam , in dependent order . They are however loaded on the first load. With gulp-uglify the files are tiny ( its now at 566Kb with 16 external libraries loading in 69ms . To put that into perspective it takes 209ms to load one google font ).
I dont know maybe i am not understanding browserify correctly but i honestly struggle to see the need for it, its seems extremely convoluted for something so simple
It is possible using external modules and an injector to do what you asked for:
I just want to easily define what files are needed in the actual view
import {UserFactory} from 'models/userFactory';
import {UserValidator} from 'models/userValidator';
import {Inject} from 'angular2/di';
and get them loaded, with angular's dependency injection handling the dependency itself.
Note: My example uses angular 2.x because I less familiar with angular 1.x and I'm sure you can do something really similar...
class SomeComponent {
userName: string;
userRating: number;
rating: number;
constructor(
#Inject(UserFactory) UserFactory
#Inject(UserValidator) UserValidator
)
{
this.UserFactory = UserFactory;
this.UserValidator = UserValidator;
}
}
Then you can use Browserify to create a bundle.js file that can be executed in a web browser.

Loading partial html template into Angular app using Laravel

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.

Resources