美文网首页
基本概念和用法-双向数据绑定 2-4

基本概念和用法-双向数据绑定 2-4

作者: 深沉的简单 | 来源:发表于2017-02-24 02:34 被阅读27次

    双向数据绑定指的是两个方向,这两个方向指的是从视图到数据模型,AngularJS是MVC框架,程序主要是通过控制器进行操作的,控制器去修改数据模型,数据模型的变更会反应到视图上。视图上面如果发生了数据变化AngularJS框架会同步到数据模型中。

    简单例子

    <!doctype html>
    <html ng-app>
        <head>
            <meta charset="utf-8">
        </head>
        <body>
            <div ng-controller="HelloAngular">
                <p>{{greeting.text}},Angular</p>
            </div>
        </body>
        <script src="js/angular-1.3.0.js"></script>
        <script src="HelloAngular_MVC.js"></script>
    </html>
    
    function HelloAngular($scope) {
        $scope.greeting = {
            text: 'Hello'
        };
    }
    

    html页面中p标签的双花口号是一个取值表达式,

    这个页面有一个问题,如果刷新页面在网络不好的情况下可能会看到{{greeting.text}}

    取值表达式与ng-bind指令

    AngularJS提供了一个叫ng-bind指令来避免上面出现取值表达式的问题,

    <!doctype html>
    <html ng-app>
        <head>
            <meta charset="utf-8">
        </head>
        <body>
            <div ng-controller="HelloAngular">
                <p><span ng-bind="greeting.text"></span>,Angular</p>
            </div>
        </body>
        <script src="js/angular-1.3.0.js"></script>
        <script src="HelloAngular_MVC.js"></script>
    </html>
    
    
    function HelloAngular($scope) {
        $scope.greeting = {
            text: 'Hello'
        };
    }
    
    

    使用ng-bind指令不会出现取值表达式的问题

    {{}}取值表达式和ng-bind间如何取舍,什么时候该使用哪个呢?

    AngularJS本身的库在记载完以后整个页面就归AngularJS来管了这个时候使用{{}}绑定的方式呢就不会有很大的问题。

    也就是说在应用主程序index中如果有数据绑定,使用ng-bind去绑定,一般在导入ng核心库的时候一般都是放在index上面,一般不会在内层去加载ng核心库,所以后续的页面通过模板加载进来的页面使用{{}}绑定就ok了。这样是不会堪当表达式的。

    在什么情况下会需要视图会修改值,然后导致去改变数据模型呢?

    典型的场景就是form表单,form是让用户可以交互和输入的。

    双向绑定的经典场景

    <!doctype html>
    <html ng-app="UserInfoModule">
    
    <head>
        <meta charset="utf-8">
        <link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css">
        <script src="js/angular-1.3.0.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" 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="推荐使用126邮箱" 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="只能是数字、字母、下划线" 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" 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" ng-click="getFormData()">获取Form表单的值</button>
                                    <button class="btn btn-default" ng-click="setFormData()">设置Form表单的值</button>
                                    <button class="btn btn-default" ng-click="resetForm()">重置表单</button>
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </body>
    
    </html>
    
    
    var userInfoModule = angular.module('UserInfoModule', []);
    userInfoModule.controller('UserInfoCtrl', ['$scope',
        function($scope) {
            $scope.userInfo = {
                email: "1319639755@qq.com",
                password: "253445528",
                autoLogin: true
            };
            $scope.getFormData = function() {
                console.log($scope.userInfo);
            };
            $scope.setFormData = function() {
                $scope.userInfo = {
                    email: '2254513188@qq.com',
                    password: 'damoqiongqiu',
                    autoLogin: false
                }
            };
            $scope.resetForm = function() {
                $scope.userInfo = {
                    email: "1319639755@qq.com",
                    password: "253445528",
                    autoLogin: true
                };
            }
        }
    ])
    
    

    预览

    以上代码创建模块,这个模块不以来任何东西,所以数组是空,

    有了模块需要建立一个控制器由控制器来控制数据模型和视图,UserInfoCtrl,这个控制器放在了form上。

    在$scope上赋一个对象userInfo,定义好登入需要的一些信息,

    然后回到html绑定值,使用ng-model绑定值。

    这样这些输入项就和数据模型绑定起来了,

    Paste_Image.png

    在$scope上建立getFormData方法,打印userInfo的数据

    如何调用$scope上的方法呢?在页面按钮标签使用ng-click="getFormData()"指令,就可以去执行$scope上的方法。

    点击获取数据按钮,就会打印userInfo的数据

    Paste_Image.png

    如果我修改了input上面的值会不会同步到数据模型中去,也就是$scope.userInfo对象上面去。

    Paste_Image.png

    答案是数据修改了,也就是说视图上的修改会自动同步到数据模型上面去,

            $scope.setFormData = function() {
                $scope.userInfo = {
                    email: '2254513188@qq.com',
                    password: 'damoqiongqiu',
                    autoLogin: false
                }
            };
    

    也可以通过程序修改数据模型,视图同步改变。

            $scope.resetForm = function() {
                $scope.userInfo = {
                    email: "1319639755@qq.com",
                    password: "253445528",
                    autoLogin: true
                };
            }
    

    重置表单

    动态切换标签样式

    双向数据绑定还可以用在修改样式上面,

    .text-red {
        background-color: #ff0000;
    }
    .text-green {
        background-color: #00ff00;
    }
    
    
    <!doctype html>
    <html ng-app="MyCSSModule">
    
    <head>
        <meta charset="utf-8">
        <link rel="stylesheet" href="CSS1.css">
    </head>
    
    <body>
        <div ng-controller="CSSCtrl">
            <p class="text-{{color}}">测试CSS样式</p>
            <button class="btn btn-default" ng-click="setGreen()">绿色</button>
        </div>
    </body>
    <script src="js/angular-1.3.0.js"></script>
    <script src="CSS1.js"></script>
    
    </html>
    
    
    var myCSSModule = angular.module('MyCSSModule', []);
    myCSSModule.controller('CSSCtrl', ['$scope',
        function($scope) {
            $scope.color = "red";
            $scope.setGreen = function() {
                $scope.color = "green";
            }
        }
    ])
    
    
    Paste_Image.png Paste_Image.png

    ng-class

    这种方式有一个问题,真实项目中标签结构很复杂,如果{{}}里面的值取错了,或者说没有值,取成了null,就会发生一些比较诡异的情况。

    为了避免这种状况AngularJS提供了ng-class指令,

    ng-class和原生的class是有去别的,它支持是可以接收一些表达式的 。

    .error {
        background-color: red;
    }
    .warning {
        background-color: yellow;
    }
    
    
    
    <!doctype html>
    <html ng-app="MyCSSModule">
    
    <head>
        <meta charset="utf-8">
        <link rel="stylesheet" href="NgClass.css">
    </head>
    
    <body>
        <div ng-controller='HeaderController'>
            <div ng-class='{error: isError, warning: isWarning}'>{{messageText}}</div>
            <button ng-click='showError()'>Simulate Error</button>
            <button ng-click='showWarning()'>Simulate Warning</button>
        </div>
    </body>
    <script src="js/angular-1.3.0.js"></script>
    <script src="NgClass.js"></script>
    
    </html>
    
    
    var myCSSModule = angular.module('MyCSSModule', []);
    myCSSModule.controller('HeaderController', ['$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.isWarning = true;
                $scope.isError = false;
            };
        }
    ])
    
    
    

    <div ng-class='{error: isError, warning: isWarning}'>{{messageText}}</div>

    这行代码使用了ng-class,他是一个表达式,如果isError的值是true他就会用error这个样式,如果isWarning的值是true他就会用warning这个样式,

    var myCSSModule = angular.module('MyCSSModule', []);
    myCSSModule.controller('HeaderController', ['$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.isWarning = true;
                $scope.isError = false;
            };
        }
    ])
    
    
    

    这段js代码中一开始是两个值都是false,底下两个按钮分别执行两个不同的方法,

    Paste_Image.png Paste_Image.png

    ng-show和ng-hide

    控制一个标签的显示和隐藏,

    <!doctype html>
    <html ng-app="MyCSSModule">
    
    <head>
        <meta charset="utf-8">
    </head>
    
    <body>
        <div ng-controller='DeathrayMenuController'>
            <button ng-click='toggleMenu()'>Toggle Menu</button>
            <ul ng-show='menuState.show'>
                <li ng-click='stun()'>Stun</li>
                <li ng-click='disintegrate()'>Disintegrate</li>
                <li ng-click='erase()'>Erase from history</li>
            </ul>
        <div/>
    </body>
    
    <script src="js/angular-1.3.0.js"></script>
    <script src="NgShow.js"></script>
    
    </html>
    
    
    
    var myCSSModule = angular.module('MyCSSModule', []);
    myCSSModule.controller('DeathrayMenuController', ['$scope',
        function($scope) {
            $scope.menuState={show:false};
            $scope.toggleMenu = function() {
                $scope.menuState.show = !$scope.menuState.show;
            };
        }
    ])
    
    

    这个例子是点击按钮切换列表项的显示状态,

    <ul ng-show='menuState.show'> menuState.show这个模型的值

    按钮点击运行toggleMenu方法

    
            $scope.toggleMenu = function() {
                $scope.menuState.show = !$scope.menuState.show;
            };
    

    每次运行都会区一个和之前相反的值,也就是区非。

    Paste_Image.png Paste_Image.png

    这是一种开关效果。

    ng-hide是和ng-show是想反的动作

    ngAnimate

    相关文章

      网友评论

          本文标题:基本概念和用法-双向数据绑定 2-4

          本文链接:https://www.haomeiwen.com/subject/usuiwttx.html