Как шаблон проектирования Model-View-Controller (MVC) работает в AngularJS?

| Пятница, 2 августа, 2013

Метки: AngularJS, Javascript Комментарии: 0

Пример с аргументами у метода контроллера
<body ng-controller="SpicyCtrl">
   <input ng-model="customSpice" value="wasabi">
   <button ng-click="spicy('chili')">Chili</button>
   <button ng-click="spicy(customSpice)">Custom spice</button>
   <p>The food is {{spice}} spicy!</p>
</body>
function SpicyCtrl($scope) {
   $scope.spice = 'very';
   $scope.spicy = function(spice) {
      $scope.spice = spice;
   }
}

В данном примере у контроллера SpicyCtrl теперь только один метод spicy, который принимает только один аргумент spice. Все элементы шаблона теперь ссылаются только на этот один метод. И передают ему, либо строку "chili", либо по нажатии другой кнопки передается значение из связанного текстового поля ввода.

Пример наследования контроллера

Наследование контроллеров в Angular основано на наследовании области видимости. Рассмотрим пример:

<body ng-controller="MainCtrl">
   <p>Good {{timeOfDay}}, {{name}}!</p>
   <div ng-controller="ChildCtrl">
      <p>Good {{timeOfDay}}, {{name}}!</p>
      <p ng-controller="BabyCtrl">Good {{timeOfDay}}, {{name}}!</p>
   </div>
</body>
function MainCtrl($scope) {
   $scope.timeOfDay = 'morning';
   $scope.name = 'Nikki';
}
	 
function ChildCtrl($scope) {
   $scope.name = 'Mattie';
}
	 
function BabyCtrl($scope) {
   $scope.timeOfDay = 'evening';
   $scope.name = 'Gingerbreak Baby';
}

Здесь в шаблоне разместили три вложенных директивы ngController. Эта конструкция шаблона даст в результате нам 4 области видимости, созданных специально для нашего преставления:

  • Корневая область видимости
  • Область видимости контроллера MainCtrl
  • Область видимости ChildCtrl, перекрывает модель name, а из предыдущей области видимости наследует timeOfDate

Наследованность работает между контроллерами таким же способом, как и между моделями.

Примечание: Стандартное прототипное наследование между двумя контроллерами не работает, как и следовало ожидать, потому что контроллеры не создаются непосредственно Angular, а скорее применяются к объекту области видимости.

Тестирование контроллеров

Хотя существует много способов тестирования контроллеров, одним из лучших по мнениям разрабочиков, является внедрение объектов $rootScope и $controller.

Допустим, есть контроллер:

function myController($scope) {
   $scope.spices = [{"name":"pasilla", "spiciness":"mild"},
               {"name":"jalapeno", "spiceiness":"hot hot hot!"},
               {"name":"habanero", "spiceness":"LAVA HOT!!"}];
   $scope.spice = "habanero";
}

И тест этого контроллера:

describe('myController function', function() {
 
  describe('myController', function() {
    var scope;
 
    beforeEach(inject(function($rootScope, $controller) {
      scope = $rootScope.$new();
      var ctrl = $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');
    });
  });
});

Если нужно протестировать вложенный контроллер, то нужно создать ту же самую иерархию области видимости в тесте, которая была создана в DOM.

describe('state', function() {
    var mainScope, childScope, babyScope;
 
    beforeEach(inject(function($rootScope, $controller) {
        mainScope = $rootScope.$new();
        var mainCtrl = $controller(MainCtrl, {$scope: mainScope});
        childScope = mainScope.$new();
        var childCtrl = $controller(ChildCtrl, {$scope: childScope});
        babyScope = childScope.$new();
        var babyCtrl = $controller(BabyCtrl, {$scope: babyScope});
    }));
 
    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(babyScope.timeOfDay).toBe('evening');
        expect(babyScope.name).toBe('Gingerbreak Baby');
    });
});

Комментарии
Никто еще не оставил здесь комментарий.
Войдите, чтобы написать комментарий , или воспользуйтесь формой ниже.
 

Copyright © CodeHint.ru 2013-2024 (v2.4.7 - работает на Angular Universal)Калькулятор инвест-портфеля