Как передавать данные между отдельными компонентами без использования $ scope?

Я составляю компонент, который содержит 3 дочерних компонента таким образом:

   

Основной компонент содержит список героев. Компонент заголовка содержит две кнопки, которые, как предполагается, должны переключать представление основного компонента на список или представление сетки.

Проблема, с которой я сталкиваюсь сейчас, заключается в передаче данных из компонента header в основной компонент. Поэтому, когда я нажимаю кнопку сетки, вид основного содержимого должен меняться в виде сетки, то же самое для представления строки.

Как можно передавать данные между дочерними компонентами в угловом 1.5?

Компонентный подход

Я предлагаю вам согласовать с подходом «Угловой 2» и использовать подход ввода / вывода . Если вы это сделаете, вы сможете легко перейти на Angular 2, потому что компоненты будут концептуально идентичными (с разницей только в синтаксисе). Так вот как вы это делаете.

Поэтому мы хотим, чтобы заголовок и основные компоненты делили часть состояния с заголовком, чтобы изменить его. Есть несколько подходов, которые мы можем использовать, чтобы заставить его работать, но самым простым является использование свойства промежуточного родительского controllerа. Итак, предположим, что родительский controller (или компонент) определяет это свойство view вы хотите использовать как заголовком (может читать и изменять), так и основными (может читать) компонентами.

Компонент заголовка : вход и выход.

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

 .component('headerComponent', { template: ` 

Header component

List Table `, controller: function() { this.setView = function(view) { this.view = view this.onViewChange({$event: {view: view}}) } }, bindings: { view: '<', onViewChange: '&' } })

Наиболее важная часть здесь - привязки. С view: '<' мы указываем, что компонент header сможет читать внешнее что-то и связывать его как свойство вида собственного controllerа. С onViewChange: '&' компоненты определяют выходные данные: канал для уведомления / обновления внешнего мира с тем, что ему нужно. Компонент Header будет вытолкнуть некоторые данные через этот канал, но он не знает, что с ним будет делать родительский компонент, и это не должно волновать.

Таким образом, это означает, что controller header может использоваться как

  

Основной компонент : вход.

Основной компонент проще, ему нужно только определить ввод, который он принимает:

 .component('mainComponent', { template: ` 

Main component

Main view: {{ $ctrl.view }} `, bindings: { view: '<' } })

Родительский взгляд

И, наконец, все это связано друг с другом:

   

Посмотрите и играйте с простой демонстрацией.

 angular.module('demo', []) .controller('RootController', function() { this.view = 'table' }) .component('headerComponent', { template: ` 

Header component

List Table `, controller: function() { this.setView = function(view) { this.view = view this.onViewChange({$event: {view: view}}) } }, bindings: { view: '<', onViewChange: '&' } }) .component('mainComponent', { template: `

Main component

Main view: {{ $ctrl.view }} `, bindings: { view: '<' } })
   
Root view: {{ root.view }}

Хотя подход с родительским компонентом (передача данных через атрибуты) является идеальной и надежной реализацией, мы можем добиться того же самого более простым способом с использованием фабрики магазинов .

В основном, данные хранятся в Store , на который ссылаются в области обоих компонентов, что позволяет реагировать на обновления пользовательского интерфейса при изменении состояния.

Пример:

 angular .module('YourApp') // declare the "Store" or whatever name that make sense // for you to call it (Model, State, etc.) .factory('Store', () => { // hold a local copy of the state, setting its defaults const state = { data: { heroes: [], viewType: 'grid' } }; // expose basic getter and setter methods return { get() { return state.data; }, set(data) { Object.assign(state.data, data); }, }; }); 

Затем в ваших компонентах вы должны иметь что-то вроде:

 angular .module('YourApp') .component('headerComponent', { // inject the Store dependency controller(Store) { // get the store reference and bind it to the scope: // now, every change made to the store data will // automatically update your component UI this.state = Store.get(); // ... your code }, template: ` 
...
...
... ` }) .component('mainComponent', { // same here, we need to inject the Store controller(Store) { // callback for the switch view button this.switchViewType = (type) => { // change the Store data: // no need to notify or anything Store.set({ viewType: type }); }; // ... your code }, template: ` ... `

Если вы хотите увидеть рабочий пример, проверьте этот CodePen .

При этом вы также можете включить связь между 2 или N компонентами . Вам просто нужно:

  1. вводить зависимость магазина
  2. убедитесь, что вы привязываете данные хранилища к области вашего компонента

как в примере выше ( ).

В реальном мире типичное приложение должно управлять большим количеством данных, поэтому имеет смысл логически разделять области данных каким-то образом. Следуя тому же подходу, вы можете добавить еще магазины . Например, чтобы управлять текущей зарегистрированной информацией пользователя и внешним ресурсом (например, каталогом), вы можете создать UserStore и CatalogStore – альтернативно UserModel и CatalogModel ; эти объекты также будут хорошими местами для централизации таких вещей, как общение с внутренними компонентами, добавление пользовательской бизнес-логики и т . д. Управление данными будет в конечном итоге Store фабрик Store .

Имейте в виду, что мы мутируем данные хранилища . Хотя этот подход мертв простым и понятным, он может плохо масштабироваться, потому что он будет давать побочные эффекты . Если вы хотите что-то более продвинутое (неизменность, чистые функции, дерево с одним состоянием и т. Д.), Проверьте Redux или, если вы, наконец, захотите переключиться на Angular 2, посмотрите на ngrx / store .

Надеюсь это поможет! 🙂

Вам не нужно делать это с помощью Angular 2 way, потому что на случай, если вы будете иногда мигрировать … Сделайте это, если это имеет смысл для вас сделать это.

Для достижения этого используйте специальные события. вы можете передавать сообщение через ваше приложение с помощью диспетчеров событий $emit(name, args); or $broadcast(name, args); $emit(name, args); or $broadcast(name, args); И вы можете слушать эти события, используя метод $ on (name, listenener);

Надеюсь, поможет

Ссылка: https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$emit

Пример: вы можете уведомлять об изменениях, как показано ниже, из компонента header

 $rootScope.$emit("menu-changed", "list"); 

И вы можете слушать изменения в директиве основного компонента, например

 $rootScope.$on("menu-changed", function(evt, arg){ console.log(arg); }); 
  • Тестирование. Невозможно разрешить все параметры для (ClassName)
  • Как создать службу Singleton в Angular 2?
  • Передача данных с предметами и прокси
  • Могут ли ленивые модули использовать один и тот же экземпляр службы, предоставляемой их родителями?
  • Как запустить функцию jquery в Angular 2 после каждой загрузки компонента
  • Угловой HttpClient не отправляет заголовок
  • Что эквивалентно ngShow и ngHide в Angular?
  • Ошибка TypeScript в коде Angular2: не удается найти имя 'module'
  • Обработка токенов обновления с использованием rxjs
  • Локальное хранение в Угловом 2
  • Угловой HTTP GET с ошибкой TypeScript http.get (...) .map не является функцией в
  • Interesting Posts

    Нет видеовыхода

    Что делать, когда Linux gui зависает

    Как использовать ссылочные параметры в C ++?

    Почему WordPress помещает «text / rocketscript» вместо «text / javascript» при использовании wp_register_script ()?

    Я защищаюсь от программного обеспечения сетевого мониторинга, если используется HTTPS?

    Холст HTML5 и сглаживание

    Windows 10 Ubuntu Bash Shell: как смонтировать другие диски Windows?

    Лучший способ синхронизации локальной базы данных HTML5 (WebSQL Storage, SQLite) с сервером (двухсторонняя синхронизация)

    Django: отображение изображения в интерфейсе администратора

    Markdown «одиночная страница» веб-приложение PHP с предварительным просмотром в реальном времени?

    Как найти файлы, которые больше / меньше, чем x байтов?

    Как использовать значение переменной как имя другой переменной в bash

    В каком порядке переопределяют таблицы стилей CSS?

    Безопасное открытие порта в брандмауэре для ПК, подключенного к Интернету

    Пустые белые значки рабочего стола на новой установке Windows 7

    Давайте будем гением компьютера.