Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 18.09.2013, 22:36
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

Взаимодействие контроллеров друг с другом
Всем привет

Интересует вопрос взаимодействия "несвязанных" друг с другом контроллеров. Упрощенный пример верстки:

<div ng-controller="Controller1" ng-scope>
... some
</div>
...
<div ng-controller="Controller2" ng-scope>
... some
</div>


Насколько я понимаю, "по-феншую" в ангуляре для взаимодействия контроллеров я должен использовать "объект-посредник":
angular


    .module( 'app', [])


    .factory( '$mediator', function() {
        return { /* code */  };
    })


    .controller( 'Controller1', function( $scope, $mediator ) {
        var model = $scope.model = {};
    })

    .controller( 'Controller2', function( $scope, $mediator ) {
        var model = $scope.model = {};
    });


Я и не против.
В чем проблема: приходится периодически обмениваться сообщениями/данными одному контроллеру с другим или наоборот. Для этих целей создаю изолированный scope и использую его реализацию подписки на события и поджиг событий. Выглядит это так:
angular
    
    
    .module( 'app', [])


    .factory( '$mediator', function( $rootScope ) {
        return $rootScope.$new( true ); // isolate
    })


    .controller( 'Controller1', function( $scope, $mediator ) {
        var model = $scope.model = {
            field: null
        };

        // subscribe to event
        $mediator.$on( 'my:event', function( event, data ) {
            // ...
        });
    })

    .controller( 'Controller2', function( $scope, $mediator ) {
        var model = $scope.model = {
            field: null
        };

        // fire event
        $mediator.$emit( 'my:event', 'data' );
    });

Работает, но: поджиг события в изолированном scope ($mediator) вызывает пересчет обработчиков всего приложения при данной реализации, а этого хотелось бы избежать.

Кто-что думает на этот счет? Возможно, все проще, чем кажется

Только не надо предлагать для обмена событиями обещания. Они, насколько мне известно, "одноразовые".

Спасибо )
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
Ответить с цитированием
  #2 (permalink)  
Старый 18.09.2013, 22:54
Профессор
Отправить личное сообщение для DjDiablo Посмотреть профиль Найти все сообщения от DjDiablo
 
Регистрация: 04.02.2011
Сообщений: 1,815

$emit Передает событие вверх по иерархии областей
broadcast Передает событие вниз для всех дочерних областях (и их детей)
http://jsfiddle.net/simpulton/XqDxG/
В примере rootScope применяется но можно и изолированный использовать.

а еще можно так
<!doctype html>
<html ng-app="project">
<head>
	<title>Angular: Service example</title>
	<script src="http://code.angularjs.org/angular-1.0.1.js"></script>
	<script>
var projectModule = angular.module('project',[]);

projectModule.factory('theService', function() {  
	return {
		thing : {
			x : 100
		}
	};
});

function FirstCtrl($scope, theService) {
	$scope.thing = theService.thing;
	$scope.name = "First Controller";
}

function SecondCtrl($scope, theService) {	
	$scope.someThing = theService.thing; 
	$scope.name = "Second Controller!";
}
	</script>
</head>
<body>	
	<div ng-controller="FirstCtrl">
		<h2>{{name}}</h2>
		<input ng-model="thing.x"/>    		
	</div>

	<div ng-controller="SecondCtrl">
		<h2>{{name}}</h2>
		<input ng-model="someThing.x"/>     		
	</div>
</body>
</html>
__________________
Лучше калымить в гандурасе чем гандурасить на колыме

Последний раз редактировалось DjDiablo, 19.09.2013 в 01:15.
Ответить с цитированием
  #3 (permalink)  
Старый 18.09.2013, 23:06
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

Сообщение от DjDiablo
broadcast Передает событие имя вниз для всех дочерних областях (и их детей)
http://jsfiddle.net/simpulton/XqDxG/
не дочитал )

1. Я создаю изолированный scope. Какой вверх/вниз?
2. Я отключил ControllerTwo от подписки на событие http://jsfiddle.net/XqDxG/528/ При каждом клике по кнопке, происходит пересчет отключенного "контроллера". Как этого избежать?
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
Ответить с цитированием
  #4 (permalink)  
Старый 18.09.2013, 23:57
Профессор
Отправить личное сообщение для DjDiablo Посмотреть профиль Найти все сообщения от DjDiablo
 
Регистрация: 04.02.2011
Сообщений: 1,815

ты меня озадачил)
я тоже недоумеваю почему он срабатывает.

Как еще один вариант пиши свой Observable

Пример для читателей, нерв и сам напишет

factory( '$mediator', function() {
        return {
            events:{},
            fire:function(name,param){
              var listeners=this.events[name],
              length=listeners.length,
              i=0;

              for(;i<length;i++){
                 listeners[i](param)
              }

            },
            on:function(name,callback)  {
                this.events[name]=events[name]||[];
                this.events[name].push(callback);
            }
        }
})
__________________
Лучше калымить в гандурасе чем гандурасить на колыме

Последний раз редактировалось DjDiablo, 19.09.2013 в 00:40.
Ответить с цитированием
  #5 (permalink)  
Старый 19.09.2013, 00:30
Профессор
Отправить личное сообщение для DjDiablo Посмотреть профиль Найти все сообщения от DjDiablo
 
Регистрация: 04.02.2011
Сообщений: 1,815

ГЫГЫ.
посмотри вот на этот эксперемент
Твой медиатор вообще не при делах

Ни чего в голову кроме отказа от ng show не приходит.
Тобиш замены ngshow на
$scope.$watch('message',function(){
        alert('изменился message')
        //тут какой то аналог ng show
    });

watch работает корректно.
Интересно заглянуть внутрь ng show и узнать в чем секрет его поведения

Взглянул, https://github.com/angular/angular.j...ShowHide.js#L3 ГЫГЫГЫ
__________________
Лучше калымить в гандурасе чем гандурасить на колыме

Последний раз редактировалось DjDiablo, 19.09.2013 в 01:39.
Ответить с цитированием
  #6 (permalink)  
Старый 19.09.2013, 01:22
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

Сообщение от DjDiablo
Как еще один вариант пиши свой Observable
уже написан. Только service на factory заменить. До некоторых пор не было в нем особой надобности. Видимо, время пришло

Сообщение от DjDiablo
ГЫГЫ.
посмотри вот на этот эксперемент
Твой медиатор вообще не при делах
Кажется, я понял - в рамках цикла ангуляра происходит обновление всего DOM.
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
Ответить с цитированием
  #7 (permalink)  
Старый 19.09.2013, 01:39
Профессор
Отправить личное сообщение для DjDiablo Посмотреть профиль Найти все сообщения от DjDiablo
 
Регистрация: 04.02.2011
Сообщений: 1,815

Взглянул, https://github.com/angular/angular.j...ShowHide.js#L3

Ты функцию слушаеш, единственный способ узнать что она вернула это выполнить ее
http://jsfiddle.net/ThpUH/
То есть ангуляр действует абсолютно логично так как выяснить что возвращает функция можно только через вызов функции. А вдруг ты через фабрику связал контролы, откуда ангуляр знает ? Вот он и вызывает ту функцию которую ты прописал так как другого варианта выяснить нет.

Замени в ngShow функцию на свойство, и оперируй свойством если не хочешь чтобы при каждом обновлении дергалась функция
__________________
Лучше калымить в гандурасе чем гандурасить на колыме

Последний раз редактировалось DjDiablo, 21.09.2013 в 22:40.
Ответить с цитированием
  #8 (permalink)  
Старый 30.09.2013, 08:37
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 554

Так-так-так. А чем обычный объект-посредник не угодил? Не могу понять, зачем здесь, вообще, события? Какая практическая задача?
Ответить с цитированием
  #9 (permalink)  
Старый 01.10.2013, 20:47
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

Сообщение от Shitbox2
А чем обычный объект-посредник не угодил? Не могу понять, зачем здесь, вообще, события? Какая практическая задача?
я "слушаю" скролл документа и только при определенном значении скролла, надо что-то делать. Т.о., если я каждое значение скролла отправляю через скоп, я пересчитываю все приложение много-много раз.

Разумеется, скролл я слушаю с... эм... скажем так, не на каждое событие скролла тригерю событие (потому, что их очень много и часто), а только на последнее.
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
Ответить с цитированием
  #10 (permalink)  
Старый 03.10.2013, 07:50
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 554

Цитата:
я "слушаю" скролл документа
Тут сам бог велел отсылать события в глобальный $rootScope, без всяких изолированных областей, т.к. событие само по себе глобальное)

А, вообще, в Ангуляр не мешало бы добавить директиву для скроллинга для навешивания на window, textarea и т.п.

Последний раз редактировалось Shitbox2, 03.10.2013 в 08:00.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как обратится к функций в другом файле jei Общие вопросы Javascript 8 11.03.2013 13:29
Запуск функций друг за другом frolvict jQuery 7 09.08.2011 21:50
Взаимодействие со скриптом на протяжении его выполнения Malgin AJAX и COMET 6 23.08.2010 22:39
Как реализовать взаимодействие окон? JSTalker ExtJS 1 29.06.2010 14:29
rand в php два рендома друг с другом связаны Jekel Серверные языки и технологии 31 26.03.2010 18:12