- 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 eachonclickevent so that wealert()a different message, however, because of the createdclosurewe 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 isundefinedin 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
Provideris 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. AServiceacts as a constructor, called with thenewoperator, this means that we can write our function in the same way that we write a simple Object constructor. OurServicewill be instantiated once and used throughout the application. As we write theservicewe are able to use thethiskeyword 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
floatproperty 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. Thefloatproperty actually takes theblocklevel<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. Thefloatalso 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.