It's time to give these web pages some dynamic features - use AngularJS! We have added a test for the controller to be added later.
There are many types of code architectures for an application. For AngularJS applications, we encourage the use of model-view-controller (MVC) mode to decouple code and separate concerns. With this in mind, we use AngularJS to add some models, views, and controllers to our application.
Please reset the working directory:
git checkout -f step-2
Our app now has a list of three phones.
The most important differences between Step 1 and Step 2 are listed below. , you can go to GitHub to see the complete difference.
Views and templates
In AngularJS, a view is a mapping after the model is rendered through HTML** templates. This means that no matter when the model changes, AngularJS will update the junction points in real time and update the view.
For example, the view component is built by AngularJS using the following template:
<html ng-app><head> ... <script src="lib/angular/angular.js"></script> <script src="js/controllers.js"></script></head><body ng-controller="PhoneListCtrl"> <ul> <li ng-repeat="phone in phones"> {{phone.name}} <p>{{phone.snippet}}</p> </li> </ul></body></html>We just replaced the statically encoded mobile phone list because we can achieve the same effect using the ngRepeat directive and two AngularJS expressions wrapped in curly braces - {{phone.name}} and {{phone.snippet}}.
The ng-repeat="phone in phones" statement inside the <li> tag is an AngularJS iterator. This iterator tells AngularJS to use the first <li> tag as a template to create a <li> element for each phone in the list.
As we learned in Step 0, curly braces wrapped around phone.name and phone.snippet identify data binding. Unlike constant calculations, the expression here is actually a data model reference we applied, and we have set these in the PhoneListCtrl controller.
Models and controllers
The data model is initialized in the PhoneListCtrl controller (here is just a function containing an array, and the objects stored in the array are mobile data list):
app/js/controller.js:
function PhoneListCtrl($scope) { $scope.phones = [ {"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 very important 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 link the presentation layer, data and logic components:
PhoneListCtrl - The name of the controller method (in the JS file controllers.js) matches the value of the ngController directive in the <body> tag.
The data of the phone is now associated with the scope ($scope) injected into our controller function. When the application starts, a root scope is created, and the controller scope is a typical successor to the root scope. The scope of this controller is valid for data bindings inside all <body ng-controller="PhoneListCtrl"> tags.
AngularJS's scope theory is very important: a scope can be regarded as a bonder for templates, models and controllers to work together. AngularJS uses scopes, as well as information, data models and controllers in templates. These can help separate the model and view, but they are indeed synchronized! Any changes to the model will be reflected on the view immediately; any changes to the view will be reflected in the model immediately.
For a more in-depth understanding of AngularJS scope, please refer to the AngularJS scope documentation.
test
The "AngularJS method" makes it very easy to test code during development. Let's take a look at the following unit test newly added for the controller:
test/unit/controllersSpec.js:
describe('PhoneCat controllers', function() { describe('PhoneListCtrl', function(){ it('should create "phones" model with 3 phones', function() { var scope = {}, ctrl = new PhoneListCtrl(scope); expect(scope.phones.length).toBe(3); }); }); });This test verifies that there are three records in our mobile phone array (no need to understand 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 of them.
When writing tests, AngularJS developers tend to use syntax in the Jasmine behavior-driven development (BBD) framework. Although AngularJS does not force you to use Jasmine, all the tests we have in the tutorial are written in Jasmine. You can get relevant knowledge on Jasmine's official homepage or on the Jasmine Wiki.
AngularJS-based projects are pre-configured to use JsTestDriver to run unit tests. You can run the test like this:
On a separate terminal, enter the angular-phonecat directory and run ./scripts/test-server.sh to start the test (please enter ./scripts/test-server.bat on the Windows command line to run the script, and the script commands run in the following way);
Open a new browser window and go to http://localhost:9876;
Select Capture this browser in strict mode.
At this time, you can leave your window alone and forget about it. JsTestDriver will complete the test and output the results to your terminal.
Run ./scripts/test.sh to test.
You should see results similar to the following:
Chrome: Runner reset..Total 1 tests (Passed: 1; Fails: 0; Errors: 0) (2.00 ms) Chrome 19.0.1084.36 Mac OS: Run 1 tests (Passed: 1; Fails: 0; Errors 0) (2.00 ms)
yeah! The test passed! Or no... Note: If an error occurs after you run the test, close the browser and go back to the terminal and close the script, and then repeat the steps above.
practise
Add another data binding for index.html. 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 "Hello, World!" appears
Create a simple table with an iterator:
<table> <tr><th>row number</th></tr> <tr ng-repeat="i in [0, 1, 2, 3, 4, 5, 6, 7]"><td>{{i}}</td></tr></table>Now let the i of the data model expression increase by 1:
<table> <tr><th>row number</th></tr> <tr ng-repeat="i in [0, 1, 2, 3, 4, 5, 6, 7]"><td>{{i+1}}</td></tr></table>Make sure to change toBe(3) to toBe(4) and then run the ./scripts/test.sh script again
Summarize
You now have a dynamic application of model, view, controller separation, and you are always testing. Now, you can go to step 3 to add a full-text search function to the application.
The above is the information sorting out the AngularJS template. We will continue to add relevant information in the future. Thank you for your support to this site!