Upon learning Angular Route Styles, It's easier to apply different styles on different templates.
Since it makes it so dynamic, I was wondering if there's a library to append scripts file(s) dynamically within the route configuration on a particular template like Angular Route Styles for stylesheet?
More like this (focusing more on js: "app/controller/template.js")
$routeProvider.when("/",
{
templateUrl: "template.html",
controller: "TemplateCtrl",
css: "css/template.css",
js: "app/controller/template.js"
});
I was planning to write an external js file for the controller of the template. Thus of course, removing the property controller: "TemplateCtrl" on the configuration file. But this would make things more easier for code management.
Related
Started learning AngularJS today, using webpack and ES6. I'm kind of stuck on a simple problem that I cannot figure out. I'm building a really simple SPA app, like a shopping cart app, which should have the "header" component with a couple of links to other pages and the sum and total of shopping cart.
One of these other controllers could be just a random dummy page, one could be the shopping cart summary, and the main controller would be where the user can actually add items to the shopping cart.
What I have thus far is just the following routes:
export default function routes($stateProvider) {
$stateProvider
.state('main', {
url: '/',
template: require('./main.html'),
controller: 'MainController',
controllerAs: 'main'
})
.state('other', {
url:'/other',
template: require('./other.html'),
controller: 'OtherController',
controllerAs: 'other',
})
}
index.js:
export default angular.module('app.main', [uirouter, productService])
.config(routing)
.controller('MainController', MainController)
.controller('OtherController', OtherController)
.name;
productService isn't relevant here, so I exclude that code.
Just as a test I tried to set the OtherController as a separate view in index.html:
<body>
<div ui-view="other"></div>
<div class="container" ui-view></div>
</body>
Kind of like suggested here: How to update partial of html using ES6 syntax with angular-webpack-seed
Also tried to use ng-controller="other" instead of ui-view="other", but that throws error:
The controller with the name 'other' is not registered
And I don't know where I would then register it...
Some places I read that you could use a directive for making a "header"/navbar, but that doesn't seem correct to me at all. Also tried that though, in this way: https://stackoverflow.com/a/33714913/6294072 Read about ng-include, but that wouldn't work, since I need the service for the shopping cart.
I am missing something fundamental here, but can't figure it out. My brain is also (unfortunately) wired on Angular (4), since I have some experience with that :)
Sorry for the noob question, I feel ashamed, but I have been struggling for this for hours now and therefore going crazy. Help is very much appreciated!
Use components instead of controllers with controllerAs. You'll find it much more similar to Angular 4. Then depending on how you want to do it, you can use either bindings or requires to create relationships between your components.
Since you have tight control over this, I would go with requires. Create a component with your navbar and stuff in it, then create child components and require the parent in them. We have a generic in-house framework for this stuff. The outer component we call the site, so we get a reference to it in our child components like this:
require: { site: '^f1Site' }
If you're not already doing so, use ui-router 1.0.x and use route to component to handle navigation & state.
Index.html just has <f1-site>Loading</f1-site> in it's body.
The f1-site template has basic layout stuff in it - including navbars and such that we've moved off into their own components - and then the ui-view directive is on the tag where we want to load all of dynamic components.
I am creating web application using Angular js in ES6. I just started learning angular. I have following questions which I couldn't understand much from resources in internet.
1) I am using ui-router for routing based on states. I have following code in my controller
myApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home);
$stateProvider
.state('contact', {
url: '/contact',
templateUrl: 'contact.html',
controller: myContactController
});
};
Contact.html:
<div ng-controller=”myContactController”>
….
</div>
Question:
a) I have specified the controller in my state in js. Should I need to specify the controller using ng-controller in my view also? What is the difference and why its necessary ?
2) I have a base module for my app.
Base module - Index.js :
import subapp1 from ‘./subApp1/index’;
angular.module(“myapp”,[subapp1]);
subApp1/index.js
Export default function(){
Angular. module(“subApp1”,[]);
};
Question:
a) Is this the right way of injecting sub module dependency in to base module?If not which is the best way to inject module dependency in to base module?
b) I would appreciate if I can get best links to understand dependency injection and different scopes in angular js in basic way.
I have specified the controller in my state in js. Should I need to specify the controller using ng-controller in my view also? What is the difference and why its necessary ?
You don't need to use ngController in HTML. Router will fetch HTML template and compile it with specified controller.
I have a base module for my app...
You specify dependent module by its name, so your setup could look like this (note, how you export name property of the Angular module):
export default angular.module('subApp1', [])
.factory('someService', semeService) // For example, attach some module service
.directive('someDirective', someDirective) // ... or some components
.name;
and then
import subapp1 from './subApp1/index';
import subapp2 from './subApp2/index';
angular.module('myapp', [
subapp1,
subapp2
]);
1.a) no, you shouldn't. If you do, you'll have two instances of the controller
2.a) no. First you don't "inject" a module into another module: a module depends on another one, that's all. That has nothing to do with dependency injection. And the syntax for that is
angular.module('myapp', ['subApp1']);
I.e. the elements of the array must be names of module you depend on. And of course, these modules must themselves be defined (before or after, it doesn't matter), using
angular.module('subApp1', []);
2.b) https://docs.angularjs.org/guide
I am minifying an angular project through gulp.This project contains index.html,css,libraries,app.js(Angular module containing routing layer+controllers) and views.
I could easily minify+concat all js files,libraries and css files into one bundle file.HTML files were also easily minified but the problem is i have routing in my app.js which render templateUrl like
.state('dashboard.home', {
url: '/home',
templateUrl: 'app/views/dashboard/home.html'
})
Now,beacause of this routing i cannot minify+concat all html files into one.because each route renders one view with its file name while there will be only one file named bundle.html.
Here,I need a guideline about how to handle this situation.
Thanks Regards
I use the gulp-ng-template for this:
gulpfile.js:
var ngTemplate = require('gulp-ng-template');
....
gulp.task('templates', function () {
return gulp.src(['view1.html', 'view2.html'])
.pipe(ngTemplate({filePath: 'js/tpl.js'}))
.pipe(gulp.dest('test'));
});
ngTemplate combines your views and puts them into the single file js/tpl.js that will look like this:
angular.module('ngTemplates').run(['$templateCache', function($templateCache) {
$templateCache.put('view1.html', '<div class="test">A</div>\n');
$templateCache.put('view2.html', '<div class="test">\n <span>B</span>\n</div>\n');
}]);
Now all you need is to include this file into your index.html. Your views will be available to the angular compiler at their original paths. You don't need to include your original html views into project any more.
You can add this file js/tpl.js to your index.html manually or by using ng-html-replace.
Instead of concatenating all templates into one html file you should use $templateCache angular provider and convert all of your html templates into JavaScript code. By using templateCache you can put all of your teplates into one file and it will work perfectly with routing mechanism. Try this gulp module Gulp ng templates
I have been tasked with setting up a initial application structure for a large angular application, I came across a few blog posts that basically said everything should be a directive (which I mostly agree with) but I have a feeling I have took this idea too far..
what I have got is basically - when you navigate to portal ui-router will load the portal template from the templates folder, all that's inside that actual template is <portal-view></portal-view.. the portalView directive basically the entire view wrapped up in a directive.
Route
angular.module('portal').config([
'$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
$stateProvider.state('portal', {
url: "/",
templateUrl: "templates/portal.tpl.html"
});
}]);
portal.tpl.html
<div class="container">
<portal-view></portal-view>
</div>
portalView directive
angular.module('portal').directive('portalView', function() {
return {
controller: 'portalController',
controllerAs: 'vm',
templateUrl: "/directives/portalView/portalView.tpl.html"
}});
portalView folder
portalView
portalView.controller.js
portalView.js
portalView.less
portalView.tpl.html
In my head this seems a good idea but I can it becoming a chore when we start adding more view to the application but I am hoping some angular pro will tell me this is the best way to do it :)
Any help, advice and links would be much appreciated!
Componentizing the view and putting it into directive looks like a smart idea to me. This will ease the migration to another router also if it takes place.
portal.tpl.html is unnecessary if you plan to follow this practice, template: '<portal-view></portal-view>' would be enough. But don't reject it if you have plans on using the template for css and js asset loading (using the scripts in templates isn't straight-forward, but it is possible), it would fit the scheme quite well.
Background: Let's suppose for the sake of argument that you have 100,000 views (partials). Let's also suppose you have accompanying view-scoped controllers, and potentially view-scoped services and filters as well. Try to envision an aggregating application that hosts 100,000 disparate small applications.
Issue: When you have "partials" that require accompanying controllers, the typical solution is to do something like this:
$routeProvider.when('/app1', {
templateUrl: 'partials/view1.html',
controller: 'controller1'
});
The controller is typically loaded from index.html via:
<script src="js/directives/Controller1.js"></script>
The problem with this approach is that it doesn't scale. There are solutions out there for dynamically loading controllers, but they still require adding touch points in various config.
Ideal Solution: Ideally - again for very small applications whose numbers are in the 000's, the controller could be loaded dynamically, and from within the partial itself. This would alleviate the need to manage several files and several configuration touch points (not to mention network requests), and keep each partial very well contained.
It would look something like this:
In router:
$routeProvider.when('/apps/:appId', {
templateUrl: 'partials/app-frame.html',
controller: 'AppCtrl'
});
In containing html (app-frame) include the relatively disparate "mini app":
<h1>Currently hosting {{appId}}</h1><hr>
<div class="ng-include: appUrl"></div>
In partial resolved with appUrl, define controller and markup in one:
<script>
myApp.controller('controller1', ['$scope', function ($scope) {
$scope.foo = "bar";
}]);
</script>
<div ng-controller="controller1">
{{foo}}
</div>
For cases like this, where there are a lot of partials and a 1-1 mapping for controller and view, it can make sense to couple the two for development efficiencies and maintenance. It's a lot cleaner than using several files and additional configuration touch points.
The problem is, this doesn't work. It could be as simple as forcing the script to load prior to applying the directive... but not sure how to do that?
Here are some similar explanations of the problem:
https://groups.google.com/forum/#!topic/angular/H4haaMePJU0
Loading Partial Page With Angular and Compile The Controller
Igor from the AngularJS team says:
I see.. we looked into supporting script tags in jqlite, but what needs to be done to get a cross-browser support involves a lot of black magic. For this reason we decided that for now we are just going to recommend that users use jquery along with angular in this particular case. It doesn't make sense for us to rewrite one third of jquery to get this working in jqlite.
But I don't know what he means by "use jquery" ... JQuery is already loaded into the application from index.html (and prior to angularjs), but it sounds like I need to do something specifically within the partial itself.
You cannot add new controllers through module('app').controller(name, function() { .. }) after AngularJS bootstrap. In order make it work you should use $controllerProvider.register(name, function() { .. }).
You can override the original controller registering function in following way to be able to add controllers pre and pos bootstrap:
var app = angular.module('app', [
'ui.router'
]);
app.config(function($controllerProvider) {
app.controller = function (name, controller) {
$controllerProvider.register(name, controller);
};
});