• angular学习(三)—— Controller


    转载请写明来源地址:http://blog.csdn.net/lastsweetop/article/details/51190079
    Controller介绍
    在angular中,controller由javascript的构造函数定义,主要用于增强angular的scope。

    当controller通过ng-controller directive与DOM关联。angular将用指定的controller构造函数实例化一个新的controller对象,同一时候一个新的child scope将被创建,然后以參数$scope注入到controller中。

    假设controller使用了controller as a语法,那么控制器实例将会分配给这个属性a。在第一章有说到这样的情况。能够返回去看下,这里就不再写演示样例了。

    使用controller的情况:

    • $scope中对象的初始化
    • 给$scope中对象添加一些行为

    不使用controller的情况:

    • 操作DOM,controller应该只包括业务逻辑,把显示的逻辑放到controller中会影响它的可測试性,angular有非常多数据绑定和封装了DOM操作的directives,全然不是必需去操作DOM。

    • 格式化输入,用angular form controls取代
    • 过滤输出,用angular filters取代
    • 在controller直接共享代码或状态。用angular services取代
    • 管理其它组件的生命周期(如创建一个service实例)

    scope对象初始化
    通常情况下,你创建一个angular应用时,你须要先设置scopescope设置一些属性。包括在view中预先声明的model。全部$scope的属性在controller注冊的DOM里都是可用的。

    以下的样例演示怎样创建一个controller,而且初始化scope对象。

        var myApp = angular.module('myApp', []);
    
        myApp.controller('GreetingController', ['$scope', function ($scope) {
            $scope.greeting = 'Hola!';
        }]);

    我们创建了一个angular module : myApp。然后调用module的controller方法。给module添加了一个controller构造函数。

    再看下controller相相应的DOM,greeting属性做了数据绑定,能够显示在controller中的值。

    <div ng-controller="GreetingController">
      {{ greeting }}
    </div>

    给scope对象添加一些行为
    为了响应一些事件或者在view中进行一些计算,我们必须为$scope添加一些行为。

    我们通过为$scope对象添加方法的方式为他添加行为。这些方法能够被template/view调用。

    以下的演示样例演示怎样为controller添加方法

    var myApp = angular.module('myApp',[]);
    
    myApp.controller('DoubleController', ['$scope', function($scope) {
      $scope.double = function(value) { return value * 2; };
    }]);

    controller一旦被加入到DOM中,该方法就能够在template中被调用

    <div ng-controller="DoubleController">
      Two times <input ng-model="num"> equals {{ double(num) }}
    </div>

    Controller演示样例
    为了进一步说明angular controller是怎样工作的,我们再来一个程序,包括以下一些组件:

    • 一个template。包括2个按钮和一条消息
    • 一个model,包括字符串spice
    • 一个controller,包括2个位spice赋值的函数

    在模板中的消息包括一个spice model,默认设置为very。点击按钮时给spice赋值。通过data binding的方式自己主动更新这条消息。


    index.html

    <div ng-controller="SpicyController">
     <button ng-click="chiliSpicy()">Chili</button>
     <button ng-click="jalapenoSpicy()">Jalapeño</button>
     <p>The food is {{spice}} spicy!</p>
    </div>

    app.js

    var myApp = angular.module('spicyApp1', []);
    
    myApp.controller('SpicyController', ['$scope', function($scope) {
        $scope.spice = 'very';
    
        $scope.chiliSpicy = function() {
            $scope.spice = 'chili';
        };
    
        $scope.jalapenoSpicy = function() {
            $scope.spice = 'jalapeño';
        };
    }]);

    输出结果
    这里写图片描写叙述
    要注意以下几点:

    • ng-controller directive 隐式地为template创建了一个scope,这个scope又被SpicyController controller管理。
    • 不过一个简单的javascript函数。命名规范是大写字母开头,以Controller结束。
    • 为scope分配一个属性去创建和更新model
    • controller的方法能够通过直接赋值的方式创建
    • controller的方法或者属性在template中是可用的

    带參数的Controller方法演示样例
    controller的方法也能够带參数,我们来改动一下上面的演示样例

    index.html

    <div ng-controller="SpicyController">
     <input ng-model="customSpice">
     <button ng-click="spicy('chili')">Chili</button>
     <button ng-click="spicy(customSpice)">Custom spice</button>
     <p>The food is {{spice}} spicy!</p>
    </div>

    app.js

    var myApp = angular.module('spicyApp2', []);
    
    myApp.controller('SpicyController', ['$scope', function($scope) {
        $scope.customSpice = "wasabi";
        $scope.spice = 'very';
    
        $scope.spicy = function(spice) {
            $scope.spice = spice;
        };
    }]);

    SpicyController只定义了一个spicy方法,这种方法须要传入spice參数。

    第一个按钮固定传入一个chili的參数。第二个按钮传入一个与输入框绑定的model 属性customSpice。

    Scope继承演示样例
    controller被使用在不同的DOM层次结构中是非经常见的。一旦ng-controller directive创建了一个子的scope,那么就得到了一个相互继承的scope层次结构。

    每个controller的$scope都能够訪问比他更高层级controller定义的属性和方法。


    index.html

    <div class="spicy">
        <div ng-controller="MainController">
            <p>Good {{timeOfDay}}, {{name}}!</p>
    
            <div ng-controller="ChildController">
                <p>Good {{timeOfDay}}, {{name}}!</p>
    
                <div ng-controller="GrandChildController">
                    <p>Good {{timeOfDay}}, {{name}}!</p>
                </div>
            </div>
        </div>
    </div>

    app.js

    var myApp = angular.module('scopeInheritance', []);
    myApp.controller('MainController', ['$scope', function($scope) {
        $scope.timeOfDay = 'morning';
        $scope.name = 'Nikki';
    }]);
    myApp.controller('ChildController', ['$scope', function($scope) {
        $scope.name = 'Mattie';
    }]);
    myApp.controller('GrandChildController', ['$scope', function($scope) {
        $scope.timeOfDay = 'evening';
        $scope.name = 'Gingerbread Baby';
    }]);

    app.css

    div.spicy div {
        padding: 10px;
        border: solid 2px blue;
    }

    这里创建了三个ng-controller directives。这样就为view创建了四个scope:

    • root scope
    • MainController scope,包括了timeOfDay和name两个属性
    • ChildController scope,继承了timeOfDay但覆盖了name属性
    • GrandChildController scope。覆盖了timeOfDay和name两个属性

    Controller中方法的继承和属性一样。因此我们之前样例的属性都能够被返回字符串的方法取代。

    Controller測试
    Controller Definition:

    var myApp = angular.module('myApp',[]);
    
    myApp.controller('MyController', function($scope) {
      $scope.spices = [{"name":"pasilla", "spiciness":"mild"},
                       {"name":"jalapeno", "spiciness":"hot hot hot!"},
                       {"name":"habanero", "spiciness":"LAVA HOT!!"}];
      $scope.spice = "habanero";
    });

    Controller Test:
    虽然有非常多种方法測试angular,但最好的一种就是通过注入$rootScope和$controller的方式

    describe('myController function', function() {
    
      describe('myController', function() {
        var $scope;
    
        beforeEach(module('myApp'));
    
        beforeEach(inject(function($rootScope, $controller) {
          $scope = $rootScope.$new();
          $controller('MyController', {$scope: $scope});
        }));
    
        it('should create "spices" model with 3 spices', function() {
          expect($scope.spices.length).toBe(3);
        });
    
        it('should set the default value of spice', function() {
          expect($scope.spice).toBe('habanero');
        });
      });
    });

    假设你想測试一个嵌套的controller,那你必须创建一样嵌套的scope。

    describe('state', function() {
        var mainScope, childScope, grandChildScope;
    
        beforeEach(module('myApp'));
    
        beforeEach(inject(function($rootScope, $controller) {
            mainScope = $rootScope.$new();
            $controller('MainController', {$scope: mainScope});
            childScope = mainScope.$new();
            $controller('ChildController', {$scope: childScope});
            grandChildScope = childScope.$new();
            $controller('GrandChildController', {$scope: grandChildScope});
        }));
    
        it('should have over and selected', function() {
            expect(mainScope.timeOfDay).toBe('morning');
            expect(mainScope.name).toBe('Nikki');
            expect(childScope.timeOfDay).toBe('morning');
            expect(childScope.name).toBe('Mattie');
            expect(grandChildScope.timeOfDay).toBe('evening');
            expect(grandChildScope.name).toBe('Gingerbread Baby');
        });
    });





    假设我的文章对您有帮助,请用支付宝打赏:

  • 相关阅读:
    scikit-learn与数据预处理
    TensorFlow2.0(11):tf.keras建模三部曲
    机器学习回顾篇(11):支持向量机(SVM)
    机器学习回顾篇(10):感知机模型
    TensorFlow2.0(10):加载自定义图片数据集到Dataset
    机器学习回顾篇(9):K-means聚类算法
    FRP代理及其在数据库安全上的实践
    Elasticsearch系列---实战零停机重建索引
    Elasticsearch系列---索引管理
    Elasticsearch系列---搜索执行过程及scroll游标查询
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/7297412.html
Copyright © 2020-2023  润新知