It's time to give these pages some dynamic features--with angularjs!. Here we have added a test for the controller to be added later.
There are many kinds of code schemas for an application. For ANGULARJS applications, we encourage decoupling of code and separation of concerns using the model-view-controller (MVC) pattern. With this in mind, we use ANGULARJS to add some models, views, and controllers to our application.
Please reset your working directory:
Git checkout-f step-2
Our app now has a list of three phones.
The most important differences between steps 1 and 2 are listed below. , you can go to GitHub to see the full difference.
Views and templates
In Angularjs, a view is a map after the model is rendered through an HTML template . This means that, regardless of when the model changes, ANGULARJS updates the union point in real-time and updates the view with it.
For example, the view component is ANGULARJS with the following template:
<HTMLNg-app><Head> ... <Scriptsrc= "Lib/angular/angular.js"></Script> <Scriptsrc= "Js/controllers.js"></Script></Head><BodyNg-controller= "Phonelistctrl"> <ul> <Ling-repeat= "Phone in phones">{{Phone.name}}<P>{{Phone.snippet}}</P> </Li> </ul></Body></HTML>
We just replaced the static coded phone list, because here we use the ngrepeat instruction and the two ANGULARJS expressions wrapped in curly braces--and-- {{phone.name}}
{{phone.snippet}}
to achieve the same effect.
- The
<li>
statement inside the tag ng-repeat="phone in phones"
is a angularjs iterator. This iterator tells Angularjs <li>
to create an element for each phone in the list with the first label as a template <li>
.
- As we learned in the No. 0 step, the
phone.name
curly braces that wrap phone.snippet
around and surround them identify data bindings. Unlike constant calculations, the expression here is actually a reference to a data model we apply, which we have set up in the PhoneListCtrl
controller.
Models and controllers
The PhoneListCtrl
data Model is initialized in the controller (this is just a function that contains an array, and the object stored in the array is a list of mobile data):
app/js/controller.js:
function Phonelistctrl ($scope) { = [ {"name": "Nexus S", "snippet": "Fast just got Faster with Nexus S. " }, {"name": "Motorola xoom™with wi-Fi ","snippet": "The next, next Generation tablet." }, {"name": "MOTOROLA xoom™", "snippet": "The next, next Generation tablet." } ];}
Although the controller does not seem to play a controlling role, it plays a crucial role here. Given the context of our data model, the controller allows us to establish data binding between the model and the view. This is how we relate the presentation layer, the data, and the logical parts together:
PhoneListCtrl
--The name of the Controller method (in the JS file controllers.js
) <body>
matches the value of the ngcontroller instruction inside the tag.
- The data for the phone is now associated with the scope () injected into our controller function
$scope
. Once an app is started, a root scope is created, and the scope of the controller is a typical successor to the root scope. The scope of this controller is <body ng-controller="PhoneListCtrl">
valid for data binding within all tags.
The scope theory of ANGULARJS is important: a scope can be seen as a glue that works together as a template, model, and controller. Angularjs uses scopes, as well as information in templates, data models, and controllers. These can help separate the model from the view, but they are really synchronous! Any changes to the model are immediately reflected in the view, and any changes to the view are immediately reflected in the model.
For more in-depth understanding of the scope of ANGULARJS, see the Angularjs scope document.
Test
The "Angularjs mode" makes development-time code testing very simple. Let's take a look at this. New unit tests added for the controller:
Test/unit/controllersspec.js:
function () { describe() { It (function() {var Scope = {}, new Phonelistctrl (scope); Expect (scope.phones.length). ToBe (3); } );});
This test verifies that there are three records in our cell phone array (no need to figure out this test script for the time being). This example shows how easy it is to create a unit test for ANGULARJS code. Because testing is an essential part of software development, we make it easy to build tests in angularjs to encourage developers to write more about them.
When writing tests, ANGULARJS developers tend to use the syntax in the Jasmine behavior-driven Development (BBD) framework. Although ANGULARJS does not force you to use Jasmine, all of the tests we have in the tutorial are written using Jasmine. You can get the information on Jasmine's official homepage or Jasmine wiki.
ANGULARJS-based projects are preconfigured to run unit tests using Jstestdriver. You can run tests like this:
- On a separate terminal, go to the
angular-phonecat
directory and run ./scripts/test-server.sh
to start the test (the Windows command line please enter .\scripts\test-server.bat
to run the script, the script command runs the same way);
- Open a new browser window and go to http://localhost:9876;
Select "Capture this browser in strict mode".
At this point, you can leave your window open and forget about it. Jstestdriver will run the test itself and output the results in your terminal.
Run ./scripts/test.sh
to test.
You should see results similar to the following:
Chrome: RunnerReset. . Total 1Tests(Passed: 1; Fails: 0; Errors: 0) (2.00Ms) chrome 19.0. 1084.36 mac Os: run 1 tests ( passed: 1; fails: 0; errors 0) (2.00 Ms)
Yes! The test passed! Or not ...
Note: If an error occurs after you run the test, close the browser and then go back to the terminal to close the script, and then on the back side of the steps above.
Practice
To index.html
add another data binding. For example:
< P > Total number of phones: {{phones.length}}</p>
Create a new data model property and bind it to the template. For example:
$scope. Hello = "Hello, world!"
Update your browser and make sure to show "Hello, world!"
Create a simple table with an iterator:
<Table> <TR><th>Row number</th></TR> <TRng-repeat= "I in [0, 1, 2, 3, 4, 5, 6, 7]"><TD>{{i}}</TD></TR> </Table>
Now let the data model expression i
increase by 1:
<Table> <TR><th>Row number</th></TR> <TRng-repeat= "I in [0, 1, 2, 3, 4, 5, 6, 7]"><TD>{{i+1}}</TD></TR> </Table>
Make sure the toBe(3)
toBe(4)
unit test fails after you change it, and then run the ./scripts/test.sh
script again
Summarize
You now have a model, a view, a controller separate dynamic application, and you are ready to test. Now you can go to step one to add full text search to your app.