Возможно ли, чтобы один контроллер использовал другой?
Например:
Этот HTML-документ просто печатает сообщение, доставленное MessageCtrl
контроллером в messageCtrl.js
файл.
<html xmlns:ng="http://angularjs.org/">
<head>
<meta charset="utf-8" />
<title>Inter Controller Communication</title>
</head>
<body>
<div ng:controller="MessageCtrl">
<p>{{message}}</p>
</div>
<!-- Angular Scripts -->
<script src="http://code.angularjs.org/angular-0.9.19.js" ng:autobind></script>
<script src="js/messageCtrl.js" type="text/javascript"></script>
</body>
</html>
Файл контроллера содержит следующий код:
function MessageCtrl()
{
this.message = function() {
return "The current date is: " + new Date().toString();
};
}
Который просто печатает текущую дату;
Если бы мне нужно было добавить еще один контроллер, DateCtrl
который вернул MessageCtrl
бы дату в определенном формате , как бы это сделать? Структура DI, кажется, касается XmlHttpRequests
и доступа к услугам.
javascript
html
angularjs
BanksySan
источник
источник
Ответы:
Существует несколько способов связи между контроллерами.
Лучшим, вероятно, является предоставление услуги:
Другой способ - отправка события в области видимости:
В обоих случаях вы можете общаться с любой директивой.
источник
Смотрите эту скрипку: http://jsfiddle.net/simpulton/XqDxG/
Также посмотрите следующее видео: Связь между контроллерами
Html:
JavaScript:
источник
Если вы хотите вызвать один контроллер в другой, доступны четыре метода
Контроллер и его область действия могут быть разрушены, но $ rootScope остается в приложении, поэтому мы берем $ rootScope, потому что $ rootScope является родительским для всех областей.
Если вы осуществляете общение от родителя к ребенку, и даже ребенок хочет общаться со своими братьями и сестрами, вы можете использовать $ broadcast
Если вы осуществляете связь от ребенка к родителю, братьев и сестер не будет, тогда вы можете использовать $ rootScope. $ Emit
HTML
Код Angularjs
В приведенном выше коде консоль $ emit 'childEmit' не будет вызывать внутри дочерних братьев и сестер и будет вызывать только внутри родителя, где $ broadcast также вызывается внутри братьев и сестер и родителя. Это место, где производительность вступает в действие. предпочтительнее, если вы используете связь ребенка с родителем, потому что она пропускает некоторые грязные проверки.
Это один из лучших способов: если вы хотите установить связь между родителем и ребенком, когда ребенок хочет общаться с непосредственным родителем, тогда он не нуждается ни в каком виде $ broadcast или $ emit, но если вы хотите установить связь от родителя к ребенку, тогда вам придется использовать либо сервис, либо $ широковещательную рассылку
Например HTML: -
Angularjs
Всякий раз, когда вы используете связь потомка с родителем, Angularjs будет искать переменную внутри потомка. Если она не присутствует внутри, тогда она выберет просмотр значений внутри родительского контроллера.
AngularJS поддерживает концепции «разделения проблем» с использованием сервисной архитектуры. Сервисы являются функциями javascript и отвечают только за выполнение определенных задач. Это делает их отдельной сущностью, которую можно обслуживать и тестировать. Сервисы, используемые для внедрения с помощью механизма Dependency Injection от Angularjs.
Код Angularjs:
Это даст вывод Hello Child World и Hello Parent World. Согласно Angular docs of services Singles - каждый компонент, зависящий от сервиса, получает ссылку на один экземпляр, сгенерированный фабрикой сервисов .
Этот метод получает scope () из элемента по его идентификатору / уникальному методу class.angular.element () возвращает элемент, а scope () дает переменную $ scope другой переменной, используя переменную $ scope одного контроллера внутри другого, не является хорошей практикой.
HTML: -
Angularjs: -
В приведенном выше коде контроллеры показывают свое собственное значение в Html, и когда вы нажмете на текст, вы получите соответствующие значения в консоли. Если вы нажмете на родительский диапазон контроллеров, браузер отобразит значение child и наоборот.
источник
Вот одностраничный пример двух контроллеров, совместно использующих данные сервиса:
Также здесь: https://gist.github.com/3595424
источник
theService
обновленияthing.x
, то это изменение автоматически распространяется на <input> вFirstCtrl
иSecondCtrl
, верно? И можно также изменитьthing.x
напрямую через любой из <input> (правильно?).Если вы хотите отправлять и транслировать события для обмена данными или вызова функций между контроллерами , перейдите по этой ссылке : и проверьте ответ
zbynour
(ответ с максимальным количеством голосов). Я цитирую его ответ !!!Если область видимости firstCtrl является родительской для области secondCtrl, ваш код должен работать, заменив $ emit на $ broadcast в firstCtrl:
Если между вашими областями нет отношения родитель-потомок, вы можете вставить $ rootScope в контроллер и передать событие всем дочерним областям (т. Е. Также secondCtrl).
Наконец, когда вам нужно отправить событие из дочернего контроллера в области вверх, вы можете использовать $ scope. $ Emit. Если область видимости firstCtrl является родительской областью видимости secondCtrl:
источник
Еще две скрипки: (не сервисный подход)
1) Для контроллера
$scope
«родитель- ребенок» - использование родительского контроллера для передачи / трансляции событий. http://jsfiddle.net/laan_sachin/jnj6y/2) Использование
$rootScope
через не связанные контроллеры. http://jsfiddle.net/VxafF/источник
На самом деле использование emit и broadcast неэффективно, потому что событие всплывает вверх и вниз по иерархии областей действия, что может легко перерасти в снижение производительности для сложного приложения.
Я бы предложил использовать сервис. Вот как я недавно реализовал это в одном из моих проектов - https://gist.github.com/3384419 .
Основная идея - зарегистрировать паб-саб / шину событий как сервис. Затем добавьте эту шину событий туда, где вам нужно подписаться или публиковать события / темы.
источник
Я тоже знаю об этом.
Но я не использую его слишком часто, потому что я не люблю использовать селекторы jQuery в угловом коде.
источник
Существует метод, не зависящий от услуг,
$broadcast
или$emit
. Это подходит не во всех случаях, но если у вас есть 2 связанных контроллера, которые можно абстрагировать в директивы, вы можете использовать этуrequire
опцию в определении директивы. Это наиболее вероятно, как ngModel и ngForm общаются. Вы можете использовать это для связи между контроллерами директив, которые либо вложены, либо находятся в одном и том же элементе.Для ситуации родитель / ребенок, использование будет следующим:
И основные моменты, чтобы заставить его работать: в родительской директиве с вызываемыми методами вы должны определить их на
this
(не на$scope
):В определении дочерней директивы вы можете использовать эту
require
опцию, чтобы родительский контроллер был передан функции связи (чтобы вы могли затем вызывать функции из нее изscope
дочерней директивы.Выше можно увидеть на http://plnkr.co/edit/poeq460VmQER8Gl9w8Oz?p=preview
Директива «брат» используется аналогично, но обе директивы для одного и того же элемента:
Используется при создании метода для
directive1
:И в директиве 2 это можно вызвать с помощью
require
опции, которая приводит к передаче siblingController в функцию link:Это можно увидеть по адресу http://plnkr.co/edit/MUD2snf9zvadfnDXq85w?p=preview .
Использование этого?
Родитель: Любой случай, когда дочерние элементы должны «зарегистрироваться» вместе с родителем. Очень похоже на отношения между ngModel и ngForm. Это может добавить определенное поведение, которое может повлиять на модели. У вас также может быть что-то, основанное исключительно на DOM, где родительский элемент должен управлять позициями определенных потомков, скажем, управлять прокруткой или реагировать на нее.
Брат, позволяющий директиве изменять свое поведение. ngModel - классический случай добавления парсеров / проверки к использованию ngModel на входах.
источник
Я не знаю, если это не соответствует стандартам, но если у вас все ваши контроллеры в одном файле, то вы можете сделать что-то вроде этого:
Как вы можете видеть, IndicatorsCtrl вызывает функции updateChart двух других контроллеров при вызове updateCharts.
источник
Вы можете внедрить службу '$ controller' в свой родительский контроллер (MessageCtrl), а затем создать / внедрить дочерний контроллер (DateCtrl), используя:
$scope.childController = $controller('childController', { $scope: $scope.$new() });
Теперь вы можете получить доступ к данным из вашего дочернего контроллера, вызывая его методы как сервис.
Дайте мне знать, если возникнет проблема.
источник
Ниже приводится
publish-subscribe
подход, который не зависит от Angular JS.Контроллер параметров поиска
Контроллер вариантов поиска
Менеджер по корпоративным мероприятиям
Глобальный
источник
В Angular 1.5 это можно сделать, выполнив следующие действия:
Это родительский компонент. В этом я создал функцию, которая помещает другой объект в мой
productForms
массив - заметка - это всего лишь мой пример, эта функция может быть чем угодно.Теперь мы можем создать еще один компонент, который будет использовать
require
:Здесь дочерний компонент создает ссылку на функцию родительского компонента,
addNewForm
которая затем может быть связана с HTML и вызываться, как и любая другая функция.источник