ng-book5: Built-In Directives

Basic ng Attribute Directives

Boolean Attributes

ng-disabled: 

Use ng-disabled to bind the disabled attribute to form input fields: <input>, <textarea>, <select>, <button>.

For example, let's disable the following button until the user enters text into the text field:

<input type="text" ng-model="someProperty" placeholder="Type to Enable" />
<button ng-model="button" ng-disabled="!someProperty">A Button</button>

ng-readonly:

<input type="text" ng-model="someProperty" placeholder="Type to Enable" />
<input type="text" ng-readonly="someProperty" value="Some text here" />

ng-checked:

<label>someProperty = {{someProperty}}</label>
<input type="checkbox"
       ng-checked="someProperty"
       ng-init="someProperty = true"
       ng-model="someProperty">

ng-selected:

<label>Select Two Fish:</label>
<input type="checkbox"
       ng-model="isTwoFish"><br/>
<select>
  <option>One Fish</option>
  <option ng-selected="isTwoFish">Two Fish</option>
</select>

Boolean-like Attributes

ng-href:

When dynamically creating a URL from a property on the current scope, always use ng-href instead of href.

The issue here is that the user is able to click a link built with href before interpolation takes place, which would bring them to the wrong page.

On the other hand, by using ng-href, Angular waits for the interpolation to take place, and then activates the link's behavior:

<!DOCTYPE html>
<html ng-app="myApp">
<head>
	<script src="angular.js"></script>
</head>
<body>
<!-- Always use ng-href when href includes an {{ expression }} -->
<a ng-href="{{myHref}}">I'm feeling lucky, when I load</a> <!-- href may not load before user clicks -->
<a href="{{myHref}}">I'm feeling 404</a>
<script type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.run(function($rootScope, $timeout) {
    $timeout(function() {
    $rootScope.myHref = 'http://google.com';
    }, 2000); });
</script>
</body>
</html>

ng-src:

Angular will tell the browser to NOT fetch the image via the given URL until all expressions provided to ng-src have been interpolated.


Directives with Child Scope

The following directives create a child scope that prototypically inherits from its parent. This inheritance provides a layer of separation meant for storing methods and model objects that work together to achieve a common goal.

ng-app and ng-controller are special directives, in that they modify the scope of directives nested inside of them.

ng-app creates the $rootScope of an Angular application, while ng-controller creates a child scope that prototypically inherits from either $rootScope or another ng-controller's $scope.

ng-app:

Placing ng-app on any DOM element marks that element as the beginning of the $rootScope.

$rootScope is the beginning of the scope chain, and all directives nested under the ng-app in your HTML inherit from it.

we can use run method to access the $rootScope:

<!DOCTYPE html>
<html ng-app="myApp">
<head>
	<script src="angular.js"></script>
</head>
<body>
    {{ someProperty }}
    <button ng-click="someAction()"></button>
<script type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.run(function($rootScope) {
    $rootScope.someProperty = 'hello computer';
    $rootScope.someAction = function() {
        $rootScope.someProperty = 'hello human';
    };
});
</script>
</body>
</html>

ng-controller:

use ng-controller, which is a built-in directive whose purpose is to provide a child scopes for the directives that are nested inside.

A child $scope is simply a JavaScript object that prototypically inherits methods and properties from its parent $scope, including the application's $rootScope.

<!DOCTYPE html>
<html ng-app="myApp">
<head>
	<script src="angular.js"></script>
</head>
<body>
    <div ng-controller="SomeController">
      {{ someModel.someProperty }}
      <button ng-click="someAction()">Communicate</button>
    </div>
<script type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.controller('SomeController', function($scope) {
    $scope.someModel = {
        someProperty: 'hello computer'
    }
    $scope.someAction = function() {
        $scope.someModel.someProperty = 'hello human';
    };
});
</script>
</body>
</html>

we should notice that two differences from the previous:

1. we use $scope. Using this scope means that actions and models used on the scope will not be available everywhere in the app; they'll only be available to directives within this scope or child scopes.

2. we use $scope.someModel to generate "private" data model.Just think the code following:

<!DOCTYPE html>
<html ng-app="myApp">
<head>
	<script src="angular.js"></script>
</head>
<body>
    <div ng-controller="SomeController">
        {{ someBareValue }}
        <button ng-click="someAction()">Communicate to child</button> 
        <div ng-controller="ChildController">
            {{ someBareValue }}
            <button ng-click="childAction()">Communicate to parent</button> 
        </div>
    </div>
<script type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.controller('SomeController', function($scope) {
    $scope.someBareValue = 'hello computer';
    $scope.someAction = function() {
        $scope.someBareValue = 'hello human, from parent';
    };
})
.controller('ChildController', function($scope) {
    $scope.childAction = function() {
        $scope.someBareValue = 'hello human, from child';
    }; 
});
</script>
</body>
</html>

 Had we set our string as a property on a model object, it would have been shared via reference, which means changing the property on the child will change it on the parent:

<!DOCTYPE html>
<html ng-app="myApp">
<head>
	<script src="angular.js"></script>
</head>
<body>
    <div ng-controller="SomeController">
        {{ someModel.someValue }}
        <button ng-click="someAction()">Communicate to child</button> 
        <div ng-controller="ChildController">
            {{ someModel.someValue }}
        <button ng-click="childAction()">Communicate to parent</button> 
        </div>
    </div>
<script type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.controller('SomeController', function($scope) {
    $scope.someModel = {
        someValue: 'hello computer'
    }
    $scope.someAction = function() {
        $scope.someModel.someValue = 'hello human, from parent';
    };
})
.controller('ChildController', function($scope) {
    $scope.childAction = function() {
        $scope.someModel.someValue = 'hello human, from child';
    }; 
});
</script>
</body>
</html>


ng-include:

Use ng-include to fetch, compile, and include an external HTML fragment into your current application.

ng-switch:

We use this directive in conjunction with ng-switch-when and on="propertyName" to switch which directives render in our view when the given propertyName changes:

<input type="text" ng-model="person.name"/>
<div ng-switch on="person.name">
    <p ng-switch-default>And the winner is</p>
    <h1 ng-switch-when="Ari">{{ person.name }}</h1>
</div>

ng-if:

Use ng-if to completely remove or recreate an element in the DOM based on an expression. If the expression assigned to ng-if evaluates to a false value, then the element is removed from the DOM, otherwise a clone of the element is reinserted into the DOM.

When an element is removed from the DOM using ng-if, its associated scope is destroyed. Furthermore, when it comes back into being, a new scope is created and inherits from its parent scope using prototypal inheritance.

ng-repeat:

Use ng-repeat to iterate over a collection and instantiate a new template for each item in the collection. Each item in the collection is given its own template and therefore its own scope.

$index: iterator offset of the repeated element.

$first: true if the repeated element is first in the iterator

$middle: true if the repeated element is between the first and last in the iterator

$last: true if the repeated element is last in the iterator

$even: true if the iterator position is even.

$odd: true if the iterator position $index is odd.

ng-init:

Use ng-init to set up state inside the scope of a directive when that directive is invoked.

ng-model:

The ng-model directive binds an input, select, textarea, or custom form control to a property on the surrounding scope.It binds to the property given by evaluating the expression on the current scope. If the property doesn't already exist on this scope, it will be created implicitly and added to the scope.

ng-show/ng-hide:

ng-show and ng-hide show or hide the given HTML element based on the expression provided to the attribute.

ng-change:

This directive evaluates the given expression when the input changes:

<!DOCTYPE html>
<html ng-app="myApp">
<head>
	<script src="angular.js"></script>
</head>
<body>
<div ng-controller="EquationController"> <input type="text"
    ng-model="equation.x"
    ng-change="change()" /> <code>{{ equation.output }}</code>
</div>
<script type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.controller('EquationController', function($scope) {
    $scope.equation = {};
    $scope.change = function() {
        $scope.equation.output = Number($scope.equation.x) + 2;
    }
});
</script>
</body>
</html>

ng-form

We use ng-form when we need to nest a form within another form.

That means that the outer form is valid when all of the child forms are valid, as well.This fact is especially useful when dynamically generating forms using ng-repeat.

Because we cannot dynamically generate the name attribute of input elements using interpolation, we need to wrap each set of repeated inputs in an ng-form directive and nest these in an outer form element.

The following CSS classes are set automatically, depending on the validity of the form:

1. ng-valid when form is valid

2. ng-invalid when form is invalid

3. ng-pristine when form is pristine

4. ng-dirty when form is dirty.

To specify which JavaScript method should be called when a form is submitted, use one of the following two directives:

1. ng-submit on the form element

2. ng-click on the first button or input field of type submit.

<!DOCTYPE html>
<html ng-app="myApp">
<head>
	<script src="angular.js"></script>
	<style type="text/css">
		input.ng-invalid {
			border: 1px solid red;
		}
		input.ng-valid {
			border: 1px solid green;
		}
	</style>
</head>
<body>
<form name="signup_form" ng-controller="FormController" ng-submit="submitForm()" novalidate>
	<div ng-repeat="field in fields" ng-form="signup_form_input">
		<input type="text" name="dynamic_input" ng-required="field.isRequired" ng-model="field.name" placeholder="{{ field.placeholder }}" />
		<div ng-show="signup_form_input.dynamic_input.$dirty && signup_form_input.dynamic_input.$invalid">
			<span class="error" ng-show="signup_form_input.dynamic_input.$error.required">The field is required
			</span>
		</div>
	</div>
	<button type="submit" ng-disabled="signup_form.$invalid">
		Submit All
	</button>
</form>
<script type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.controller('FormController', function($scope) {
    $scope.fields = [
    {placeholder: 'Username', isRequired: true},
    {placeholder: 'Password', isRequired: true},
    {placeholder: 'Email (optional)', isRequired: false}
    ];
    $scope.submitForm = function() {
    	alert("it works!");
    }
});
</script>
</body>
</html>

ng-click

Use ng-click to specify a method or expression to run on the containing scope when the element is clicked:

<div ng-controller="CounterController">
	<button ng-click="count = count + 1" ng-init="count = 0">
		Increment
	</button>
	count: {{ count }}
	<button ng-click="decrement()">
		Decrement
	</button>
</div>
<script type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.controller('CounterController', function($scope) {
    $scope.decrement = function() {
    	$scope.count = $scope.count - 1;
    }
});

ng-select

<div ng-controller="CityController">
	<select ng-model="city" ng-options="city.name for city in cities">
		<option value="">Choose City</option>
	</select>
	Best City: {{ city.name }}
</div>
<script type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.controller('CityController', function($scope) {
    $scope.cities = [
    {name: 'Seattle'},
    {name: 'San Francisco'},
    {name: 'Chicago'},
    {name: 'New York'},
    {name: 'Boston'}];
});
</script>

ng-class

Use ng-class to dynamically set the class of an element by binding an expression that represents all classes to be added.

<div ng-controller="LotteryController">
	<div ng-class="{red: x > 5}" ng-if="x > 5">
		You won!
	</div>
	<button ng-click="x = generateNumber()" ng-init="x = 0">
		Draw Number
	</button>
	<p>Number is: {{ x }}</p>
</div>
<script type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.controller('LotteryController', function($scope) {
    $scope.generateNumber = function() {
    	return Math.floor((Math.random() * 10) + 1);
    }
});
</script>



你可能感兴趣的:(AngularJS)