- Closure: In the code snippet you sent below the approach is clear but you have run into something called
Closure
. What you are attempting to do here is to create a different environment for eachonclick
event so that wealert()
a different message, however, because of the createdclosure
we are actually telling our 3 buttons to share the parent environment. This means that by the time any of our buttons are clicked the loop has completed reaches an index of 3 which isundefined
in our array of strings since arrays are zero indexed in javascript.
You should research a little about Closures
and see if you can identify how to create a unique environment for each button.
<button id="btn-0">Button 1!</button>
<button id="btn-1">Button 2!</button>
<button id="btn-2">Button 3!</button>
<script type="text/javascript">
var prizes = ['A Unicorn!', 'A Hug!', 'Fresh Laundry!'];
for (var btnNum = 0; btnNum < prizes.length; btnNum++) {
// for each of our buttons, when the user clicks it...
document.getElementById('btn-' + btnNum).onclick = function() {
// tell her what she's won!
alert(prizes[btnNum]);
};
}
</script>
- Factory, Service, Provider: This is a question that has plagued just about every Angular developer at some point and you will find plenty of varying opinions so I will just give you a brief overview. A
Provider
is the base level of all 3 of these options and is the only one that you can use in theapp.config()
so for the majority of what you will be writing early on you will most likely not utilize Providers. AService
acts as a constructor, called with thenew
operator, this means that we can write our function in the same way that we write a simple Object constructor. OurService
will be instantiated once and used throughout the application. As we write theservice
we are able to use thethis
keyword to define our values and methods that we want to be exposed to our controllers. Below you will see an example of this:
function myService() {
this.hello = "Hello World";
this.goodbye = function () {
return "Goodbye";
}
}
angular.module('myApp', [])
.service('myService', myService)
.controller('myCtrl', ['myService', function(myService) {
this.message = myService.hello; // this.message is now equal to "Hello World"
}]);
For a Factory
we will need to return
our own object instead of using the this
keyword. The factory
is essentially a function that gets called each time it is injected into a controller. An example of the service
above rewritten as a factory
is:
function myFactory() {
return {
hello: "Hello World",
goodbye: function () {
return "Goodbye";
}
}
}
angular.module('myApp', [])
.factory('myFactory', myFactory)
.controller('myCtrl', ['myFactory', function(myFactory) {
this.message = myFactory.hello; // this.message is now equal to "Hello World"
}]);
-
Library vs Framework: A library is typically defined as a collection of helper methods/functions. A library, like jQuery, offers tools that we can integrate into any project very quickly. A framework takes things a step further by enforcing rules on how your application is constructed, usually through design patterns. Angular is a framework because it is structured to follow the MVC/MVVM design pattern. These patterns allow us to keep our code much more organized hopefully easy to understand.
-
CSS Float: The code example that you provided is using the
float
property which allows you to see the three items line up into a row, however, it is also doing something that you may have not realized. Thefloat
property actually takes theblock
level<div>
's, which typically try to take up the entire width of their parent and tells them to ignore that and to only take up the minimum amount of room that they need. Thefloat
also removes them from the usual flow of the parent which causes the parent to collapse because it no longer accounts for the childrens height.
Options to fix involve removing the float
rule and looking into the display
rule. There are a few options for display
that will fix this issue.