双向数据绑定
双向数据绑定是指两个方向:从数据模型到视图,从视图到数据模型。AngularJS是一个MVC框架,控制器去修改数据模型,数据模型的变更会反应到视图上。视图上发生了数据的变化,是否能够自动同步到数据模型上呢?
example.html
<html data-ng-app="helloApp">
<head>
<meta charset="utf-8">
</head>
<body>
<div data-ng-controller="helloCtrl">
<p>{{greeting.text}},Angular</p>
</div>
</body>
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
<script src="app.js"></script>
</html>
app.js
angular.module('helloApp',[])
.controller('helloCtrl',['$scope', function($scope) {
$scope.greeting = {
text : 'hello'
}
}]);
运行结果:
但是,使用这种方式进行绑定,当网页刷新过快或者网速不好时,用户有可能看到{{greeting.text}}。AngularJS提供了ng-bind来进行绑定。
将上面的example.html修改如下:
<html data-ng-app="helloApp">
<head>
<meta charset="utf-8">
</head>
<body>
<div data-ng-controller="helloCtrl">
<p><span data-ng-bind="greeting.text"></span>,Angular</p>
</div>
</body>
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
<script src="app.js"></script>
</html>
这时狂刷页面或者网络不好时,不会出现上述情况。
什么时候使用{{ }},什么时候使用ng-bind?
AngularJS本身的库在加载完了之后,整个页面都已经归Angular来管了。这时候使用双括号就不会有很大的问题。也就是说,在首页也就是index.html上如果有数据绑定,用ng-bind去绑定。后续的页面可以用双括号{{ }}。
双向数据绑定的场景:form表单
example.html
<!DOCTYPE html>
<html data-ng-app="userInfoModule">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="css/bootstrap.css">
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
<script src="form.js"></script>
</head>
<body>
<div class="panel panel-primary">
<div class="panel-heading">
<div class="panel-title">双向数据绑定</div>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-12">
<form class="form-horizontal" role="form" data-ng-controller="userInfoCtrl">
<div class="form-group">
<label class="col-md-2 control-label">
邮箱:
</label>
<div class="col-md-10">
<input type="email" class="form-control"
placeholder="推荐使用163邮箱" data-ng-model="userInfo.email">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">
密码:
</label>
<div class="col-md-10">
<input type="password" class="form-control"
placeholder="只能说数字、字母、下划线" data-ng-model="userInfo.password">
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<div class="checkbox">
<label>
<input type="checkbox" data-ng-model="userInfo.autoLogin">自动登录
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button class="btn btn-default" data-ng-click="getFormData()">获取form表单的值</button>
<button class="btn btn-default" data-ng-click="setFormData()">设置form表单的值</button>
<button class="btn btn-default" data-ng-click="resetFormData()">重置form表单</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</body>
</html>
form.js
angular.module('userInfoModule',[])
.controller('userInfoCtrl',['$scope',function($scope){
$scope.userInfo = {
email : "2549034126@qq.com",
password : "123456",
autoLogin : true
};
$scope.getFormData = function() {
console.log($scope.userInfo);
}
}])
运行结果:
点击“获取form表单的值”按钮,按f12看到控制台输出如下:
当修改了邮箱中的值时, 点击“获取form表单的值”按钮,按f12看到控制台输出如下:
可以看到,视图上的修改会自动同步到数据模型上。
通过程序修改视图的数据,前后对比如下:
重置form表单的值如下:
双向数据绑定的场景:修改css样式
example.html
<html data-ng-app="myCssModule">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="css1.css">
</head>
<body>
<div data-ng-controller="cssCtrl">
<p class="text-{{color}}">测试CSS样式</p>
<button class="btn btn-default" data-ng-click="setGreen()">绿色</button>
</div>
</body>
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
<script src="css1.js"></script>
</html>
css1.css
@charset "UTF-8";
.text-red {
background-color : #ff0000;
}
.text-green {
background-color : #00ff00;
}
css1.js
angular.module('myCssModule',[])
.controller('cssCtrl',['$scope', function($scope) {
$scope.color = "red";
$scope.setGreen = function() {
$scope.color = "green";
}
}])
运行结果:
点击按钮:
双向数据绑定的场景:修改css样式——使用ng-class
example.html
<html data-ng-app="ngClassModule">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="ngClass.css">
</head>
<body>
<div data-ng-controller="ngClassCtrl">
<div data-ng-class='{error: isError, warning: isWarning}'>{{messageText}}</div>
<button data-ng-click="showError()">Simulate Error</button>
<button data-ng-click="showWarning()">Simulate Warning</button>
</div>
</body>
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
<script src="ngClass.js"></script>
</html>
ngClass.css
@charset "UTF-8";
.error{
background-color : red;
}
.warning {
background-color : yellow;
}
ngClass.js
/**
*
*/
angular.module('ngClassModule',[])
.controller('ngClassCtrl',['$scope', function($scope) {
$scope.isError = false;
$scope.isWarning = false;
$scope.showError = function() {
$scope.messageText = "This is an error";
$scope.isError = true;
$scope.isWarning = false;
}
$scope.showWarning = function() {
$scope.messageText = "Just a warning,please carry on";
$scope.isError = false;
$scope.isWarning = true;
}
}])
运行结果:
点击Simulate Error按钮:
点击Simulate Warning按钮:
双向数据绑定的场景:控制标签的显示和隐藏ng-show、ng-hide
example.html
<html data-ng-app="ngShowModule">
<head>
<meta charset="utf-8">
</head>
<body>
<div data-ng-controller="ngShowCtrl">
<button data-ng-click="toggleMenu()">Toggle Menu</button>
<ul data-ng-show="menuState.show">
<li>平局</li>
<li>赢</li>
<li>输</li>
</ul>
</div>
</body>
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
<script src="ngShow.js"></script>
</html>
ngShow.js
/**
*
*/
angular.module('ngShowModule', [])
.controller('ngShowCtrl', ['$scope', function($scope){
$scope.menuState = {
show : false
}
$scope.toggleMenu = function() {
$scope.menuState.show = !$scope.menuState.show;
}
}])
运行结果:
点击按钮: