i noticed that AngularJS UI Bootstrap uses the following approach for templates:
angular.module("uib/template/progressbar/bar.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("uib/template/progressbar/bar.html" }
So i think it's quite nice solution but what is the reason to create module for each template url like angular.module("uib/template/progressbar/bar.html" or angular.module("uib/template/progressbar/progress.html" etc
What benefits it will give to us?
Having a module for each template separately will result in proper separation of code. Each module will Handel the code for each template and will prevent the user from mixing the code. It's quite a universal rule that a function or entity should do only its own duty and not more that that.
Related
.factory("user", userService);
function userService($q, $http) {
function User (){
//....
}
return User;
}
or
.factory("User", ["$q", "$http", function ($q, $http) {
var User = {
//....
}
return User;
}])
I often see both depending of the situation (or rather depending of the author), but I've been wondering for quite a long time now (since I've begun learning Angular), what makes it different, and if I can use one or the other without changing anything. I usually use the first one and following the logic because I find it easier, and because I'm confused with the second one. I may have made mistakes but that's why Im asking for some help. Thanks !
The second code snippet in your question is the one that I'd recommend you to use for all your angularjs services.
Angular framework offers Dependency Injection (DI) feature out of the box that can be used when defining components such as services, directives, filters, animations or when providing run and config blocks for a module.
If you define the dependencies without using an array of string in your angular app, then you are doing it wrong. This way of registering the dependencies will work well for non minified version of the JavaScript source file.
But if you intend to minify the files for production, which everyone must, then all those (dependency) arguments will be changed to something really random which angular will not be able to map to any registered component. So ultimately, an error will be thrown by the framework.
To avoid this mistake, one can just make sure to always use an array of type string to instruct the dependencies. Read this in more detail. If you are your own then you can maybe keep this tip in mind. However, if working in a team, it is good to configure this using the options below so that everyone in the team follows this. If not, then they will encounter an error.
I'd recommend you to use strict DI mode.
How to enable strict mode?
This mode can be enabled using two options as mentioned below.
Option-1:
<div ng-app="myApp" ng-strict-di>
<!-- your app here -->
</div>
Option-2:
angular.bootstrap(document, ['myApp'], {
strictDi: true
});
Learn why is strict DI mode good for your AngularJS app in my blog post.
The first form will not work with minification. The second form is required when minification is used. The reason for this is that the AngularJS injector uses the function parameter names to resolve the $q and $http dependencies in the first form. If the function parameter names are changed (e.g., by minification), that will fail. The second form relies on the strings "$q" and "$http", which will not be changed by minification.
This is discussed in step 7 of the AngularJS tutorial.
I am currently learning AngularJS on Udemy with the excellent AngularJS JumpStart with Dan Wahlin course. I am on Section 7 - Bonus: Getting Started Building Custom Directives.
I had defined a Hello World directive which was working fine; then I defined a new directive so that I could learn about shared vs isolate scope.
As soon as I include the second directive, I get the following error:
Error: [$compile:multidir] Multiple directives [helloWorld, helloWorld] asking for template on: <hello-world>
http://errors.angularjs.org/1.4.8/$compile/multidir?p0=helloWorld&p1=&p2=helloWorld&p3=&p4=template&p5=%3Chello-world%3E
Here's a Plunker.
If I comment out the script that defines either one of these, the other one works.
Why is this happening? I've clearly named both directives differently, so why is Angular throwing an error that basically says I've declared the same directive twice?
1) you forget to add "plain:true" in the directives ( if you put directly your html code in template you have to put "plain:true" otherwise use templateUrl to your html file)
2) the problem come from the fact that you create two times the same angular module :
var directives = angular.module('app').directives;
I update your plunker
http://plnkr.co/edit/cYkgdYcHXGlbtMRJHRw2?p=preview
I think the issue is defining directives variable and adding it each time to the directives.
The more popular way of defining directives is:
var app = angular.module('app');
app.directive('helloWorld', ....);
Or if you prefer it your way, either have all directives in the same file, or move var directives = angular.module('app').directives to app.js
I'm trying to slowly convert a Backbone App to Angular. It's actually using Marionette to be precise. In each of my current Marionette views, they are a Marionette.ItemView. For the template to show, I do this:
get template() {
return _.template(nameOfMyTemplate, { myModel: this.model });
}
nameOfMyTemplate would be my AwesomeTemplate.template.html file that is in my solution.
I was wondering how I could go about just passing my template.html without calling _.template in a backbone or marionette app? So somewhere in my backbone view or marionette.itemview, I could do
template: NewAwesomeAngularTemplate.template.html // where NewAwesomeAngularTemplate.template.html is a file in my solution
Has anyone come across this yet? I wasn't able to find much info on how people were converting their apps to Angular from Backbone or Marionette. Thanks in advance!
Marionette expects all templates to be immediately available, not having to be fetched async. The view.template function can be easily overwritten but it needs to immediately return a string (or return a function that will immediately return a string).
There was an old fork called Marionette.Async which enabled fetching of templates on-demand but it was abandonded long ago after the maintainers determined it to be A Really Bad Idea.
Your best bet is to build a mechanism that either loads all the templates into memory up front (like embedding them in a single JS file or the main HTML page) or a custom mechanism that ensures templates are fetched as-needed before the view gets used. The former will be much easier but viability depends on how many templates you have and how big they are.
Not too familiar with Backbone or Marionette, but went over and looked at the website.
I am not sure if this is what you are asking, so excuse me if I am way off base. In Angular you can use the ngRouter or the more powerful uiRouter to bind your urls to controllers and views.
state('index', {
url: "/",
controller: 'SomeController',
templateUrl: "template/NewAwesomeAngularTemplate.html"
})
Not sure if this is what you were looking for. If so, check out the documentation at https://github.com/angular-ui/ui-router
You can use the grunt ts html2ts support : https://github.com/grunt-ts/grunt-ts#html-2-typescript-support
It turns an html file into a typescript string variable which you can return from the template function.
Hi I would like to implement Jade templates in my AngularJS project, and have mixin in my template (reusable code).
However the problem that I am facing is that we cannot use Mixin with arguments. Am I doing it correctly or is there any alternative for the same in AngularJS that I am missing?
You can create an js object from your model and pass it as strings to the mixin like the following:
+avatarRow({name: '{{avatar.name}}', uuid: '{{avatar.uuid}}', verificationCode: '{{avatar.verificationCode}}', status: '{{avatar.status}}'})
Inside the mixin you can now access e.g. #{avatar.uuid}
I considder to automate this further, because this leads to a duplication of the models code which is not so nice yet. I will share my solution if I get one :)
I figured out that mixins cannot be used in Angular as the scope is to be defined. Hence now created element directive and passed in the template (which was meant to be written in Mixin) as the templateUrl in it.
I am new to Meteor and AngularJs. I am trying to follow the example app on https://github.com/lvbreda/Meteor_angularjs but I have not been able to get it working so far.
I am getting an error 'app is not defined' in this piece of code:
app.controller('MeteorCtrl', ['$scope', '$meteor', function ($scope, $meteor) {
Uncaught ReferenceError: app is not defined
$scope.todos = $meteor("todos").find({});
$meteor("todos").insert({
name: "Do something",
done: false
});
I tried to re-write the above as:
var MeteorCtrl = function ($scope, $meteor) {
$scope.todos = $meteor("todos").find({});
$meteor("todos").insert({
name: "Do something",
done: false
})
};
which is still throwing an error 'Error: Unknown provider: $meteorProvider <- $meteor'
The only other example of meter+angularjs at https://github.com/bevanhunt/meteor-angular-leaderboard appears to be dated.
Can someone please post a simple, but fully working, downloadable example of meteor+angularjs using the package at https://github.com/lvbreda/Meteor_angularjs?
I'm obviously biased but our team wrote and maintain this library - angular-meteor and we've also released a tutorial for combining the two - angular-meteor tutorial
While I'm not using lvbreda's Angular package, I have been able to integrate Angular with Meteor + Blade as the HTML templating language, in a relatively simple way. I started off with Daniel Olano's Ng-Meteor package, and ended up with my own implementation of a Meteor/Angular bridge. I'm new to both Meteor and Angular, but it appears to work well and I like that the code is very transparent so that I understand pretty well how it works.
I've written the following CoffeeScript module, named client/ngMeteor.coffee, which defines the bridge between Meteor and Angular:
define("ngMeteor", [], ->
angular.module('ngMeteor.directives', [])
angular.module('ngMeteor.services', [])
angular.module('ngMeteor.blade', []).run(['$templateCache', '$rootScope', '$compile',
($templateCache, $rootScope, $compile) ->
bodyTemplate = Template.body
if !bodyTemplate
throw new Error("A body template must be defined ('body.blade')")
# Render each template and place in Angular's template cache
$templateCache.put "#{key}.blade", render() for own key, render of Template
# Render the body template and have Angular compile it, then inject it into the DOM's body element
Meteor.startup(()->
# Necessary?
Spark.finalize(document.body)
$('html').attr('data-ng-app', '')
$('body').html($compile(bodyTemplate())($rootScope))
$rootScope.$apply()
)
])
angular.module 'ngMeteor', ['ngMeteor.blade', 'ngMeteor.services', 'ngMeteor.directives']
)
For a full working example see this example project of mine. Feedback is appreciated.
I just created a simple example which shows how to create a simple angular-meteor application.
The app displays some items from a mongo collection and can update the collection through the browser-console in realtime. (just default meteor features with angular-js)
It can be found on github: https://github.com/tom-muhm/angular-meteor-example.
You can find some examples in a different fork
https://github.com/alex-okrushko/Meteor_angularjs
I build an app in https://github.com/linepos/linepos but now it's not working because lvbreda changed the code
There is a different approach you can use https://github.com/kievechua/flame-on
Just had the same problem. Solved by adding meteor dependency
angular.module('meteorapp', ["meteor"]) # <------------------- Here
.config ['$routeProvider', '$locationProvider', ($routeProvider, $locationProvider) ->
$locationProvider.html5Mode(true)
$routeProvider.when '/',
controller: 'home'
]
I am also new to Meteor and Angular - and I also had a hard time to make this work. But I think I managed to get the basic Angular functionality running.
What I found out I put onto github: https://github.com/dirkk0/angularjs-meets-meteorjs
I hope this works for you, too.
I've been going at this problem myself and made a package for angural.
example code is at: https://github.com/bramtervoort/meteor-angular-stack/tree/example
example at: http://bramtervoort-todo.meteor.com
Its very simple just install meteor and run: mrt add angular-stack
My answer will be simple: don't mix meteor and angular!
Why should you?
For the data binding capabilities? Meteor does it for you much simpler than angular with helpers and the publish/subscribe mechanism.
To build you own directives? Meteor templates and Blaze do that for you too.
After having used angular for quite a while, I've used meteor recently and find it so much simpler: much less code to achieve the same, cleaner declaration of directives, a whole lot is done for you in the background, especially for pulling subsets of data.
There is no need to use angular with meteor, just use meteor. I haven't yet found a case where I needed angular with it.
The hardest concept to grasp in meteor is the publish subscribe model but once you get it, it is very powerful as you can define what data is pushed to the client with parameters. Then all you need is a template to render it.
Lookup this article for more details
https://www.discovermeteor.com/blog/understanding-meteor-publications-and-subscriptions/
EDIT: Jan 2016
Looking at benchmarks of Angular 2 in Meteor, I now can see a reason maybe to use it. That was definitely not the case with prior versions:
See the article:
http://info.meteor.com/blog/comparing-performance-of-blaze-react-angular-meteor-and-angular-2-with-meteor
Angular 1.x was way way slower than Blaze and React just 6 months ago. Angular 2 seem way better, yet I'm still not a fan of the over-complexity.
For simplicity AND speed, also look up Aurelia.io built by former Angular lead and designed to last and move with the Javascript framework itself.