共计 12939 个字符,预计需要花费 33 分钟才能阅读完成。
内置指令:所有以ng前缀开头作为命名空间的指令都是angularJS提供的内置指令。
一、基础ng属性指令
1.布尔属性
根据HTML标准的定义,布尔属性代表一个true和false值,当这个属性出现时,这个属性的值就是true,如果未出现,这个属性就是false。
- ng-disabled:使用ng-disabled可以把disabled属性绑定到一下表单输入字段上
<input/>(text,checkbox,radio,number,url,email,submit)
<textarea>
<select>
<button>例如下面的例子3秒以后按钮就能点击了。
<button ng-disabled="isDis">submit</button>
<script>
angular.module('my-app', [])
.run(function ($rootScope, $timeout) {
$rootScope.isDis = true;
$timeout(function () {
$rootScope.isDis = false;
}, 3000)
})
</script> - ng-readonly:通过ng-readonly可以将某个返回真或假的表达式同是否出现readonly属性进行绑定
<input type="text" ng-model="someProperty"/>
<input type="text" ng-readonly="someProperty" value="Some text here"/>
<script>
angular.module('my-app', [])
.run(function ($rootScope) {
$rootScope.someProperty = true;
})
</script> - ng-checked:通过ng-checked将某个表达式同是否出现checked属性进行绑定。
<lable>someProperty = {{ someProperty }}</lable>
<input type="checkbox" ng-checked="someProperty" ng-init="someProperty = true" ng-model="someProperty"/>
<script>
angular.module('my-app', [])
</script> - ng-selected:它可以对是否出现option标签的selected属性进行绑定。
<lable>Select turn:</lable>
<input type="checkbox" ng-model="isTurn"/><br/>
<select>
<option>false</option>
<option ng-selected = "isTurn">true</option>
</select>
<script>
angular.module('my-app', [])
</script>
2.类布尔属性
ng-href,ng-src等属性虽然不是布尔属性,但是由于行为相识,所以在angularJS与布尔是同等对待的。
- ng-href:当使用当前作用域中属性动态创建URL时,应该用ng-href代替href。
<a ng-href="{{ myHref }}">felling lucky,when I load</a>
<a href="{{ myHref }}">felling 404</a>
<script>
angular.module('my-app', []).run(function ($rootScope, $timeout) {
$timeout(function () {
$rootScope.myHref = "http://www.baidu.com";
}, 3000)
})
</script> - ng-src:angularJS会告诉浏览器在ng-src对应的表达式生效之前不要加载图片。
<h1>Wrong Way</h1>
<img src="{{ imgSrc }}"/>
<h1>Right Way</h1>
<img ng-src="{{ imgSrc }}"/>
<script>
angular.module('my-app', []).run(function ($rootScope, $timeout) {
$timeout(function () {
$rootScope.imgSrc = "http://www.ninthmirage.com/wp-content/themes/Teahouse-Wordpress-Theme-master/images/me.jpg";
}, 2000)
})
</script>
二、在指令中使用子作用域
指令会以父级作用域为原型生成子作用域。这种继承的机制可以创建一个隔离层,用来将需要协同工作的方法和数据模型对象放置在一起。
ng-app和ng-controller是特殊指令,因为它们会修改嵌套在它们内部的指令作用域。
ng-app为angularJS应用创建一个$rootScope,ng-controller则会以$rootScope或另一个ng-controller的作用域为原型创建新的子作用域。
- ng-app:任何具有ng-app属性的DOM元素将被标记为$rootScope起点。$rootScope是作用域链的起始点,任何嵌套在ng-app内的指令都会继承它。
<html ng-app="my-app">
<head></head>
<body>
<p>{{someProperty}}</p>
<button ng-click="someAction()">click</button>
<script>
angular.module('my-app', []).run(function ($rootScope, $timeout) {
$rootScope.someProperty = "Hello Angular";
$timeout(function () {
$rootScope.someAction = function () {
$rootScope.someProperty = "Welcome to Angular";
};
}, 500)
})
</script>
</body>
</html> - ng-controller:内置指令ng-controller的作用是为嵌套在其中的指令创建一个子作用域,避免将所有操作和模型都定义在$rootScope上。用这个指令可以在一个DOM元素上放置控制器。ng-controller接受一个表达式参数。而且这个参数必须写。子$scope只是一个JavaScript对象,其中含有从父级$scope中通过原型继承得到的方法和属性,包括应用的$rootScope。嵌套在ng-controller中的指令有访问新子$scope的权限,但是要牢记每个指令都应该遵守的和作用域相关的规则。注意:a.操作指的是$scope上标准的JavaScript方法;b.模型指的是$scope上保存的包含瞬时状态的JavaScript对象;c.持久化状态的数据应该是保存到服务中,服务的作用是处理模型的持久化;d.j绝对不要直接将控制器中$scope赋值为值类型对象(字符串,布尔值,数字);e.控制器应该尽可能简单,最好将业务逻辑移到服务和指令中。
<div ng-controller="someController">
{{someModel.someProperty}}
<button ng-click="someAction()">communicate</button>
</div>
<script>
angular.module('my-app', []).controller('someController', function ($scope) {
//创建模型
$scope.someModel = {
//添加属性
someProperty: 'hello Angular'
};
//设置$scope自身的操作
$scope.someAction = function () {
$scope.someModel.someProperty = "welcome to Angular"
};
})
</script>注意,这个例子和之前相比有相处不同。首先,我们使用$rootScope的子作用域,它提供了一个干净的对象供我们操作。其次,显式声明了数据模型。看一下这个例子的表体:
<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>
angular.module('my-app', [])
.controller('someController', function ($scope) {
//反模式,裸值
$scope.someBareValue = 'hello Angular';
//设置$scope自身的操作
$scope.someAction = function () {
$scope.someBareValue = "welcome to Angular,form parent"
};
})
.controller('childController', function ($scope) {
$scope.childAction = function () {
$scope.someBareValue = "welcome to Angular,form child"
};
})
</script>由于原型继承的关系,修改父级对象的someBareValue会同时修改子对象的值,但反之则不行 。下面这个例子的实际效果,首先点击child button,然后点击parent button。这个例子充分说明了子控制器是复制而非引用someBareValue。注意:JavaScript对象要么是值复制要么是引用复制。字符串、数字、布尔型变量是值复制;数组、对象和函数是引用复制。如果将模型对象的某个值设置为字符串,它会通过引用进行共享,因此在子$scope中修改属性也会修改父$scope中的这个属性。
<div ng-controller="someController">
{{someModel.someProperty}}
<button ng-click="someAction()">communicate to Child</button>
<div ng-controller="childController">
{{someModel.someProperty}}
<button ng-click="childAction()">communicate to parent</button>
</div>
</div>
<script>
angular.module('my-app', [])
.controller('someController', function ($scope) {
//最佳实践,使用一个模型
$scope.someModel = {
someProperty: 'hello Angular'
};
$scope.someAction = function () {
$scope.someModel.someProperty = "welcome to Angular,form parent"
};
})
.controller('childController', function ($scope) {
$scope.childAction = function () {
$scope.someModel.someProperty = "welcome to Angular,form child"
};
})
</script> - ng-include:使用ng-include可以加载,编译并包含外部HTML片段到当前应用中。模板的URL被限制在与应用文档相同的域和协议下,可以通过白名单或包装成被信任的值来突破限制。更进一步,需要考虑跨域资源共享(CORS)和同源规则(SOP)来确定模板可以在任何浏览器中正常加载。
<div ng-controller="userCtrl">
<div class="container">
<div ng-include="'include/includeHello.html'"></div>
<div ng-include="'include/includeHello2.html'"></div>
</div>
</div>
<script>
angular.module('my-app', []).controller('userCtrl', function ($scope) {})
</script>以上方式1
<div ng-controller="ExampleController" class="container">
<div ng-repeat="template in templates" ng-include="template.url"></div>
</div>
<script>
angular.module('my-app', [])
.controller('ExampleController', ['$scope', function ($scope) {
$scope.templates = [
{name: 'template1', url: 'include/error.html'},
{name: 'template2', url: 'include/includeHello2.html'}
];
}])
</script>以上方式2
- ng-switch:这个指令和ng-switch-when以及on=”propertyName”一起使用,可以在propertyName发生变化时渲染不同指令到视图中。
<div ng-controller="SomeController">
<input type="text" ng-model="person.name"/>
<div ng-switch on="person.name">
<p ng-switch-default>Add the winner id</p>
<h1 ng-switch-when="Ari">{{person.name}}</h1>
</div>
</div>
<script>
angular.module('my-app', [])
.controller('SomeController', function ($scope) {
$scope.person = {
name: "Ari"
};
});
</script> - ng-view:ng-view指令用来设置被路由管理和放置的HTML中视图的位置。
- ng-if:使用ng-if指令可以完全根据表达式的值在DOM中生成或移除一个元素。如果赋值给ng-if的表达式的值是false,那对应的元素将会从DOM中移除,否则对应元素的一个克隆将被重新插入DOM中。ng-if与ng-show和ng-hide指令最本质的区别是,它不是通过CSS显示或隐藏DOM节点,而是生成和移除节点。当一个元素被ng-if从DOM中移除,同它关联的作用域也会被销毁。而且当它重新加入DOM中时,会通过原型继承从它的父作用域中生成新的作用域。
<div ng-controller="SomeController">
<div ng-if="2+2===5">Won't see the DOM node</div>
<div ng-if="2+2===4">hi,I see the DOM node</div>
</div>
<script>
angular.module('my-app', []).controller('SomeController', function ($scope) {
});
</script> - ng-repeat:ng-repeat用来遍历一个集合或称为集合中每一个元素生成的模板实例。$index:遍历的进度(0~length-1);$first:当元素是遍历的第一个时值为true;$middle:当元素处于第一个和最后一个之间时值为true;$last:当元素是遍历的最后一个时值为true;$even:当$index值是偶数时值为true;$odd:当$index值是奇数时值为true。
<ul ng-controller="SomeController">
<style>
.odd {background-color: #00f;}
.even {background-color: red;}
</style>
<li ng-repeat="person in people" ng-class="{even:!$even,odd:!$odd}">
{{person.name}} lives in {{person.city}}
</li>
</ul>
<script>
angular.module('my-app', []).controller('SomeController', function ($scope) {
$scope.people = [
{name: "Z", city: "chengdu"},
{name: "Y", city: "shanghai"},
{name: "L", city: "beijing"},
{name: "S", city: "tianjing"},
{name: "Q", city: "guangzhou"}
];
});
</script> - ng-init:ng-init指令用来在指令被调用时设置内部作用域的初始状态。
<div ng-controller="myCtrl">
<div ng-init="getting='hello';person='Angular'">
{{getting}} {{person}}
</div>
</div>
<script>
angular.module('my-app', []).controller('myCtrl', ['$scope', function ($scope) {
}]);
</script>也可以结合ng-repeat达到综合效果
<div ng-controller="ExampleController">
<div ng-repeat="innerList in list" ng-init="outerIndex = $index">
<div ng-repeat="value in innerList" ng-init="innerIndex = $index">
<span class="example-init">list[ {{outerIndex}} ][ {{innerIndex}} ] = {{value}};</span>
</div>
</div>
</div>
<script>
angular.module('my-app', []).controller('ExampleController', ['$scope', function ($scope) {
$scope.list = [['a', 'b'], ['c', 'd']]
}]);
</script> - {{}}和ng-bind:{{}}语法是angularJS内置的模板语法,它会在内部$scope和视图之间创建绑定。基于这个绑定,只要$scope发生变化,视图就会随之自动更新。实际上它就是ng-bind的简略形式。只是这种方式不需要创建新的节点。下面两种方式其实是一样的。
<div ng-init="name='zhou'">
{{name}}
</div>
<div ng-init="name='zhou'">
<span ng-bind="name"></span>
</div> - ng-cloak:除了使用ng-bind来避免为渲染元素闪烁,还可以在含有{{}}的元素上使用ng-cloak指令。
<div ng-init="name='zhou'">
<span ng-cloak="name"></span>
</div>ng-cloak指令会将内部元素隐藏,直到路由调用对应的页面时才显示出来。
- ng-bind-template:同ng-bind指令类似,ng-bind-template用来在视图中绑定多个表达式。
<div ng-init="name='zhou';city='cd'">
<span ng-bind-template="{{name}}{{city}}"></span>
</div> - ng-model:ng-model指令用来将input,select,textarea或自定义表单控件同包含它们的作用域中的属性进行绑定。它可以提供并处理表单验证功能,在元素上设置相关你的CSS类(ng-valid,ng-invalid等),并负责在父表单中注册控件。它将当前作用域中运算表达式的值同给定元素进行绑定,如果属性不存在,它会隐式创建并将其添加到当前作用域中。
<div ng-controller="ExampleController">
<input type="text"ng-model="modelName.someProperty"/>
</div>
<script>
angular.module('my-app', []).controller('ExampleController', ['$scope', function ($scope) {
$scope.modelName = {
someProperty:'hello Angular'
}
}]);
</script> - ng-show/ng-hide:ng-show和ng-hide根据所给表达式的值来显示隐藏HTML元素。
<div ng-show="1+1===3">don't show</div>
<div ng-show="1+1===2">show</div>
<div ng-hide="1+1===3">don't hide</div>
<div ng-hide="1+1===2">hide</div> - ng-change:这个指令会在表单输入发生变化时计算给定表达式的值。这个指令常常和ng-model联合使用。
<div ng-controller="myController">
<input type="text" ng-model="equation.x" ng-change="change()"/>
<code>{{ equation.output }}</code>
</div>
<script>
angular.module('my-app', []).controller('myController', ['$scope', function ($scope) {
$scope.equation = {};
$scope.change = function () {
$scope.equation.output = parseInt($scope.equation.x) + 10
}
}]);
</script> - ng-form:这个指令用来在一个表单内部嵌套另一个表单。普通的<form>标签不允许嵌套。这意味着内部子表单都合法时,外部表单才合法。
<!--
下面的CSS类会根据表单的验证状态自动设置:
a.表单合法时设置ng-valid;
b.表单不合法时设置ng-invalid;
c.表单未进行修改时设置ng-pristion;
d.表单进行过修改时设置ng-dirty;
Angular不会将表单提交到服务器,除非它指定了action属性。要提交表单时调用下面的两个指令中的一个
ng-submit:在表单元素上使用。
ng-click:在第一个按钮或submit类型的输入字段上使用。
-->
<form ng-controller="myController" name="signup_form" 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>
<br/><br/>
</div>
<button type="submit" ng-disabled="signup_form.$invalid">Submit All</button>
</form>
<style>
input.ng-invalid {border:1px solid red;}
input.ng-valid {color:orange;border:1px solid black;}
</style>
<script>
angular.module('my-app', []).controller('myController', function ($scope) {
$scope.fields = [
{placeholder: "Username", isRequired: 'true'},
{placeholder: "Password", isRequired: 'true'},
{placeholder: "Email(optional)", isRequired: 'false'}
];
$scope.submitForm = function () {
alert("it works")
}
});
</script> - ng-click:ng-click用来指定一个元素被点击时调用的方法或表达式。
<div ng-controller="myController">
<button ng-click="count=count+1" ng-init="cout=0">+</button>
count:{{count}}
<button ng-click="decrement()">-</button>
</div>
<script>
angular.module('my-app', []).controller('myController', function ($scope) {
$scope.count = 0;
$scope.decrement = function () {
$scope.count = $scope.count - 1
}
});
</script> - ng-select/ng-options:ng-select用来将数据同HTML的<select>元素进行绑定。ng-options的值可以是一个内涵表达式,它接受一个数组或者对象,并对它们进项循环,将内部的内容提供给select标签内部的选项。
<!--
1.数组作为数据源:
用数组中的值做标签;
用数组中的值作为选中的标签;
用数组中的值作为标签组;
用数组中的值作为选中的标签组;
2.对象作为数据源:
用对象的键-值做标签;
用对象的键-值作为选中的标签;
用对象的键-值作为标签组;
用对象的键-值作为选中的标签组;
-->
<div ng-controller="myController">
<select ng-model="city" ng-options="city.name for city in cities">
<option value="">Choose City</option>
</select>
Best City:{{city.name}}
</div>
<script>
angular.module('my-app', []).controller('myController', function ($scope) {
$scope.cities = [
{name: 'beijing'},
{name: 'shanghai'},
{name: 'chegndu'},
{name: 'guangzhou'},
{name: 'hongkong'},
];
});
</script> - ng-submit:它用来将表达式同onsubmit事件进行绑定。这个指令同时会阻止默认行为(发送请求并重新刷新页面),但前提是表单不含有action属性。
<form ng-controller="myController" ng-submit="submit()">
Enter text and hit enter:
<input type="text" name="person.name" ng-model="person.name"/>
<input type="submit" name="person.name" value="Submit"/>
<code>people={{people}}</code>
<ul>
<li ng-repeat="(index,object) in people">{{object.name}}</li>
</ul>
</form>
<script>
angular.module('my-app', []).controller('myController', function ($scope) {
$scope.person = {name: null};
$scope.people = [];
$scope.submit = function () {
if ($scope.person.name) {
$scope.people.push({name: $scope.person.name});
$scope.person.name = "";
}
}
});
</script> - ng-class:使用ng-class动态设置元素的类。方法是绑定一个代表所有需要添加的类的表达式。重复的类不会添加。当表达式发生变化,先前添加的类会被移除,新类会被添加。
<style>
.red {background-color: red}
</style>
<div ng-controller="myController">
<button ng-click="x=generateNumber()" ng-init="x=0">Draw Number</button>
<p>Number is:{{x}}</p>
<div ng-class="{red:x>5}" ng-if="x>5">You won! Number > 5</div>
</div>
<script>
angular.module('my-app', []).controller('myController', function ($scope) {
$scope.generateNumber = function () {
return Math.floor((Math.random() * 10) + 1)
}
});
</script> - ng-attr-(suffix):当AngulerJS编译DOM会查找花括号{{ some expression}}内的表达式。这些表达式会被自动注册到$watch服务中并更新到$digest循环中,成为它的一部分。一些特殊的浏览器:
<h1>hello {{ Expression }}</h1>
<svg>
<circle ng-attr-exp="{{Expression}}"></circle>
</svg>