AngularJS
Угловые $ области
Поиск…
замечания
Угловое использует дерево областей для привязки логики (от контроллеров, директив и т. Д.) К виду и является основным механизмом обнаружения изменений в AngularJS. Более подробную ссылку для областей можно найти в docs.angularjs.org
Корень дерева доступен так же, как через инъекционную службу $ rootScope . Все дочерние $ scopes наследуют методы и свойства их родительской области $ scope, что позволяет детям получить доступ к методам без использования Angular Services.
Основной пример наследования $ scope
angular.module('app', [])
.controller('myController', ['$scope', function($scope){
$scope.person = { name: 'John Doe' };
}]);
<div ng-app="app" ng-conroller="myController">
<input ng-model="person.name" />
<div ng-repeat="number in [0,1,2,3]">
{{person.name}} {{number}}
</div>
</div>
В этом примере директива ng-repeat создает новую область для каждого из вновь созданных детей.
Эти созданные области являются дочерними элементами их родительской области (в данном случае областью, созданной myController), и, следовательно, они наследуют все свои доли, например, человека.
Избегайте наследования примитивных значений
В javascript, присваивая не примитивное значение (например, Object, Array, Function и многие другие), сохраняет ссылку (адрес в памяти) на заданное значение.
Присвоение примитивному значению (String, Number, Boolean или Symbol) двум переменным и изменению одного из них не изменится:
var x = 5;
var y = x;
y = 6;
console.log(y === x, x, y); //false, 5, 6
Но с не примитивное значение, поскольку обе переменные просто сохраняя ссылки на тот же объект, изменение одной переменной изменит другой:
var x = { name : 'John Doe' };
var y = x;
y.name = 'Jhon';
console.log(x.name === y.name, x.name, y.name); //true, John, John
В угловом режиме, когда создается область, ему присваиваются все свойства родителя. Однако изменение свойств впоследствии влияет только на родительскую область, если это не примитивное значение:
angular.module('app', [])
.controller('myController', ['$scope', function($scope){
$scope.person = { name: 'John Doe' }; //non-primitive
$scope.name = 'Jhon Doe'; //primitive
}])
.controller('myController1', ['$scope', function($scope){}]);
<div ng-app="app" ng-controller="myController">
binding to input works: {{person.name}}<br/>
binding to input does not work: {{name}}<br/>
<div ng-controller="myController1">
<input ng-model="person.name" />
<input ng-model="name" />
</div>
</div>
Помните: в Angular scope могут быть созданы разными способами (например, встроенные или настраиваемые директивы или функция $scope.$new()
Функция $scope.$new()
), и отслеживание дерева области видимости, вероятно, невозможно.
Использование только не-примитивных значений в качестве свойств области будет держать вас в безопасности (если вам не требуется свойство, чтобы не наследовать, или другие случаи, когда вам известно о наследовании области).
Функция, доступная во всем приложении
Будьте осторожны, этот подход может считаться плохим дизайном для угловых приложений, поскольку он требует от программистов запоминания того, где функции помещаются в дерево областей видимости, и знать о наследовании области. Во многих случаях было бы предпочтительнее вводить услугу ( Угловая практика - с использованием наследования сферы по сравнению с инъекцией) .
В этом примере показано, как можно использовать наследование областей для наших нужд и как вы могли бы воспользоваться им, а не лучшие методы проектирования всего приложения.
В некоторых случаях мы могли бы воспользоваться наложением наследования и установить функцию как свойство rootScope. Таким образом, все области приложения (за исключением изолированных областей) наследуют эту функцию и могут быть вызваны из любого места приложения.
angular.module('app', [])
.run(['$rootScope', function($rootScope){
var messages = []
$rootScope.addMessage = function(msg){
messages.push(msg);
}
}]);
<div ng-app="app">
<a ng-click="addMessage('hello world!')">it could be accsessed from here</a>
<div ng-include="inner.html"></div>
</div>
inner.html:
<div>
<button ng-click="addMessage('page')">and from here to!</button>
</div>
Создание пользовательских событий $ scope
Подобно обычным элементам HTML, для $ scopes возможно иметь собственные события. События $ scope могут быть подписаны следующим образом:
$scope.$on('my-event', function(event, args) {
console.log(args); // { custom: 'data' }
});
Если вам нужно отменить регистрацию прослушивателя событий, функция $ on вернет функцию открепления. Чтобы продолжить описанный выше пример:
var unregisterMyEvent = $scope.$on('my-event', function(event, args) {
console.log(args); // { custom: 'data' }
unregisterMyEvent();
});
Существует два способа запуска вашего собственного события $ scope event $ broadcast и $ emit . Чтобы уведомить родителя (ов) о масштабе конкретного события, используйте $ emit
$scope.$emit('my-event', { custom: 'data' });
Вышеприведенный пример вызовет прослушиватели событий для my-event
в родительской области и продолжит доведение дерева до $ rootScope до тех пор, пока слушатель не stopPropagation
на событие. Только события, вызванные с помощью $ stopPropagation
могут вызвать stopPropagation
Реверс $ emit - это $ broadcast , который инициирует прослушиватели событий во всех дочерних областях в дереве областей, которые являются дочерними элементами области, которая называется $ broadcast .
$scope.$broadcast('my-event', { custom: 'data' });
События, инициированные с помощью $ broadcast, не могут быть отменены.
Использование функций $ scope
Хотя объявление функции в корневом каталоге $ имеет свои преимущества, мы также можем объявить функцию $ scope любой частью кода, который вводится службой $ scope. Контроллер, например.
контроллер
myApp.controller('myController', ['$scope', function($scope){
$scope.myFunction = function () {
alert("You are in myFunction!");
};
}]);
Теперь вы можете вызвать свою функцию с контроллера, используя:
$scope.myfunction();
Или через HTML, который находится под этим конкретным контроллером:
<div ng-controller="myController">
<button ng-click="myFunction()"> Click me! </button>
</div>
директива
Угловая директива - это еще одно место, которое вы можете использовать в своей области:
myApp.directive('triggerFunction', function() {
return {
scope: {
triggerFunction: '&'
},
link: function(scope, element) {
element.bind('mouseover', function() {
scope.triggerFunction();
});
}
};
});
И в вашем HTML-коде под одним и тем же контроллером:
<div ng-controller="myController">
<button trigger-function="myFunction()"> Hover over me! </button>
</div>
Конечно, вы можете использовать ngMouseover для одного и того же, но что особенно важно в директивах, так это то, что вы можете настроить их так, как вы хотите. И теперь вы знаете, как использовать свои функции $ scope внутри них, быть творческими!
Как вы можете ограничить область действия директивы и почему вы это сделаете?
Область применения используется как «клей», который мы используем для связи между родительским контроллером, директивой и шаблоном директивы. Всякий раз, когда приложение AngularJS загружается, создается объект rootScope. Каждая область, созданная контроллерами, директивами и службами, прототипически унаследована от rootScope.
Да, мы можем ограничить область действия директивы. Мы можем сделать это, создав изолированную область действия для директивы.
Существует три типа директивных областей:
- Область действия: False (Директива использует свою родительскую область)
- Область действия: True (директива получает новую область)
- Область действия: {} (Директива получает новую изолированную область)
Директивы с новой изолированной областью: когда мы создаем новую изолированную область, она не будет унаследована от родительской области. Эта новая область называется изолированной областью, потому что она полностью отделена от родительской области. Зачем? мы должны использовать изолированную область действия: мы должны использовать изолированную область, когда хотим создать настраиваемую директиву, потому что она будет обеспечивать, чтобы наша директива была общей и размещалась в любом месте приложения. Родительский охват не будет мешать сфере действия.
Пример изолированного объема:
var app = angular.module("test",[]);
app.controller("Ctrl1",function($scope){
$scope.name = "Prateek";
$scope.reverseName = function(){
$scope.name = $scope.name.split('').reverse().join('');
};
});
app.directive("myDirective", function(){
return {
restrict: "EA",
scope: {},
template: "<div>Your name is : {{name}}</div>"+
"Change your name : <input type='text' ng-model='name'/>"
};
});
Существует 3 типа префиксов, которые AngularJS предоставляет для выделенной области:
- "@" (Привязка текста / односторонняя привязка)
- "=" (Привязка прямой модели / двусторонняя привязка)
- "&" (Привязка к действию / привязка метода)
Все эти префиксы получают данные из атрибутов элемента директивы, например:
<div my-directive
class="directive"
name="{{name}}"
reverse="reverseName()"
color="color" >
</div>