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');
    });
});





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

原文地址:https://www.cnblogs.com/wgwyanfs/p/7297412.html