Angular学习:控制器(未翻译完)
发布日期:2021-06-29 13:10:26 浏览次数:3 分类:技术文章

本文共 10579 字,大约阅读时间需要 35 分钟。

原文地址:

Understanding Controllers

理解控制器

In AngularJS, aController is defined by a JavaScript constructor function thatis used to augment the .

AngularJS中,一个控制器被一个JavaScript构造函数定义,用来扩大AngularJS Scope

When aController is attached to the DOM via the  directive, AngularJS willinstantiate a new Controller object, using the specified Controller's constructorfunction. A new child scope will be created and madeavailable as an injectable parameter to the Controller's constructor functionas $scope.

当一个控制器被通过ng-controller指示符附在一个DOM上,AngularJS将会实例化一个控制器对象--使用控制器的构造函数。一个新的child scope将会被创建,可以以$scope的名字,作为一个对于控制器构造方法可被注入的参数开始生效。

If thecontroller has been attached using the controller as syntaxthen the controller instance will be assigned to a property on the new scope.

如果控制器被使用controller as语法而附加上,控制器实例将会被分配给新的scope的一个属性。

Use controllersto:

  • Set up the initial state of the $scope object.
  • Add behavior to the $scope object.

使用控制器到:

  • 设置$scope对象的初始状态。
  • 给$scope对象增加行为。

Do not use controllers to:

不要使用控制器到:

  • Manipulate DOM — Controllers should contain only business logic. Putting any presentation logic into Controllers significantly affects its testability. AngularJS has  for most cases and  to encapsulate manual DOM manipulation.
  • 操控DOM----控制器应该只包含业务逻辑。把任何展示逻辑放入控制器会影响它的可测试性。AngularJS对于大多数情况有databinding和directives去封装手工的DOM操作。
  • Format input — Use  instead.
  • 表单输入----使用AngularJS form 控制替代。
  • Filter output — Use  instead.
  • 过滤输出----使用AngularJS filters替代。
  • Share code or state across controllers — Use  instead.
  • 在控制器间共享代码和状态----使用AngularJS services替代。
  • Manage the life-cycle of other components (for example, to create service instances).
  • 管理其它组件的声明周期(例如,去创建service实例)。

Setting up theinitial state of a $scope object

建立$scope对象的初始状态

Typically, whenyou create an application you need to set up the initial state for theAngularJS $scope. You set up the initial state of a scopeby attaching properties to the $scope object.The properties contain the view model (the model that will bepresented by the view). All the $scope propertieswill be available to the  at the point in the DOM wherethe Controller is registered.

典型的,当你创建一个应用,你需要去建立AngularJS$scope的初始状态。你通过给$scope对象附着上属性设置一个scope的初始状态。这些属性包含这个view model(被那个view所呈现的model)。所有这些$scope属性对于template是可用的----Controller被注册的DOM的那个点上。

The followingexample demonstrates creating a GreetingController, which attachesa greeting property containing the string 'Hola!' to the $scope:

以下例子展示了创建一个GreetingController,这附着了一个greeting属性(包含着字符串“Hola”)给$cope

var myApp =angular.module('myApp',[]);

 

myApp.controller('GreetingController', ['$scope',function($scope) {

  $scope.greeting = 'Hola!';

}]);

We createan , myApp, for our application. Then we add the controller's constructor functionto the module using the .controller() method.This keeps the controller's constructor function out of the global scope.

我们创建一个AngularJS ModulemyApp,给我们的应用。然后我们增加这个控制器的构造函数给模块----使用.controller()方法。这使得控制器的构造函数在全局范围之外。

We have used an inline injection annotation toexplicitly specify the dependency of the Controller on the $scope service provided by AngularJS. See the guide on  for moreinformation.

我们使用了一个inline injectionannotation去显式地指定被AngularJS提供的$scope service之上的控制器的依赖。参看 的指导来获取更多信息。

We attach ourcontroller to the DOM using the ng-controller directive.

我们附着我们的控制器到DOM----使用ng-controlle指示符。

The greeting property can now be data-bound to the template:

这个greeting属性现在可以被数据限制(data-bound)在模板中。

<divng-controller="GreetingController">

  {

{ greeting }}

</div>

Adding Behaviorto a Scope Object

Scope对象增加行为

In order toreact to events or execute computation in the view we must provide behavior tothe scope. We add behavior to the scope by attaching methods to the $scope object. These methods are then available to be called from thetemplate/view.

为了在view中对events或者execute computation做出反应,我们必须提供行为给scope。我们增加行为给scope----通过附着方法给$scope对象。这些方法然后在这个template/view中被调用是有效的。

The followingexample uses a Controller to add a method, which doubles a number, to thescope:

下面的例子使用一个Controller去增加方法--这个方法对一个数字进行翻倍scope

var myApp =angular.module('myApp',[]);

 

myApp.controller('DoubleController', ['$scope', function($scope){

  $scope.double = function(value) { returnvalue * 2; };

}]);

Once theController has been attached to the DOM, the double method canbe invoked in an AngularJS expression in the template:

一旦这个控制器被附着给DOM,这个double方法就可以被调用在一个AngularJS表达式中,在这个模板里面。

<divng-controller="DoubleController">

  Two times <inputng-model="num"> equals {

{ double(num) }}

</div>

As discussed inthe  section of this guide, anyobjects (or primitives) assigned to the scope become model properties. Anymethods assigned to the scope are available in the template/view, and can beinvoked via AngularJS expressions and ng eventhandler directives (e.g. ).

就像这个指南的章节讨论的,任何对象(或者原语)分配给这个scope就成为了model的属性。任何方法分配给scope就在template/view中有效,并且可以被调用,通过AngularJS的表达式和ng event handler 指示符(例如:ngClick)。

Using ControllersCorrectly

In general, aController shouldn't try to do too much. It should contain only the businesslogic needed for a single view.

The most commonway to keep Controllers slim is by encapsulating work that doesn't belong tocontrollers into services and then using these services in Controllers viadependency injection. This is discussed in the  and  sections of this guide.

Associating Controllers withAngularJS Scope Objects

You canassociate Controllers with scope objects implicitly via the  or .

Simple SpicyController Example

To illustratefurther how Controller components work in AngularJS, let's create a little appwith the following components:

  • A  with two buttons and a simple message
  • A model consisting of a string named spice
  • A Controller with two functions that set the value of spice

The message in our template contains a binding to the spice model which, by default, is set to the string "very".Depending on which button is clicked, the spice model isset to chili or jalapeño, and themessage is automatically updated by data-binding.

  Edit in Plunker

<divng-controller="SpicyController">

 <buttonng-click="chiliSpicy()">Chili</button>

 <buttonng-click="jalapenoSpicy()">Jalapeño</button>

 <p>The food is{

{spice}} spicy!</p>

</div>

Things to noticein the example above:

  • The ng-controller directive is used to (implicitly) create a scope for our template, and the scope is augmented (managed) by the SpicyController Controller.
  • SpicyController is just a plain JavaScript function. As an (optional) naming convention the name starts with capital letter and ends with "Controller".
  • Assigning a property to $scope creates or updates the model.
  • Controller methods can be created through direct assignment to scope (see the chiliSpicy method)
  • The Controller methods and properties are available in the template (for both the <div> element and its children).

Spicy ArgumentsExample

Controllermethods can also take arguments, as demonstrated in the following variation ofthe previous example.

  Edit in Plunker

<divng-controller="SpicyController">

 <inputng-model="customSpice">

 <buttonng-click="spicy('chili')">Chili</button>

 <buttonng-click="spicy(customSpice)">Custom spice</button>

 <p>The food is{

{spice}} spicy!</p>

</div>

Notice thatthe SpicyController Controllernow defines just one method called spicy, which takesone argument called spice. The templatethen refers to this Controller method and passes in a string constant 'chili' in the binding for the first button and a modelproperty customSpice (bound toan input box) in the second button.

ScopeInheritance Example

It is common toattach Controllers at different levels of the DOM hierarchy. Since the  directive creates a newchild scope, we get a hierarchy of scopes that inherit from each other.The $scope that each Controller receives willhave access to properties and methods defined by Controllers higher up thehierarchy. See  formore information about scope inheritance.

  Edit in Plunker

<divclass="spicy">

  <divng-controller="MainController">

    <p>Good {

{timeOfDay}},{
{name}}!</p>

 

    <divng-controller="ChildController">

      <p>Good {

{timeOfDay}},{
{name}}!</p>

 

      <divng-controller="GrandChildController">

        <p>Good{

{timeOfDay}}, {
{name}}!</p>

      </div>

    </div>

  </div>

</div>

Notice how wenested three ng-controller directivesin our template. This will result in four scopes being created for our view:

  • The root scope
  • The MainController scope, which contains timeOfDay and name properties
  • The ChildController scope, which inherits the timeOfDay property but overrides (shadows) the name property from the previous scope
  • The GrandChildController scope, which overrides (shadows) both the timeOfDay property defined in MainController and the name property defined in ChildController

Inheritance works with methods in the same way as it does with properties.So in our previous examples, all of the properties could be replaced withmethods that return string values.

Testing Controllers

Although thereare many ways to test a Controller, one of the best conventions, shown below,involves injecting the  and :

ControllerDefinition:

var myApp =angular.module('myApp',[]);

 

myApp.controller('MyController',function($scope) {

  $scope.spices = [{

"name":"pasilla", "spiciness":"mild"},

                   {

"name":"jalapeno", "spiciness":"hot hothot!"},

                   {

"name":"habanero", "spiciness":"LAVAHOT!!"}];

  $scope.spice = "habanero";

});

Controller Test:

describe('myControllerfunction', 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 thedefault value of spice', function() {

      expect($scope.spice).toBe('habanero');

    });

  });

});

If you need totest a nested Controller you must create the same scope hierarchy in your testthat exists in the DOM:

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 overand 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('GingerbreadBaby');

    });

});

 

转载地址:https://chaiyu2002.blog.csdn.net/article/details/54783330 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Angular学习:$q
下一篇:AngularJS学习:Angular的模块

发表评论

最新留言

表示我来过!
[***.240.166.169]2024年04月14日 17时09分20秒