2016-02-11 13 views
2

У нас есть большое приложение Angularjs 1.6, которое имеет $ rootcope, разбросанное по всему приложению в более чем 200 местах в фильтрах, сервисах, маршрутах и ​​т. Д., Поэтому его нужно реорганизовать, но я не уверен, как узнать, когда нужно удалить Это. Когда лучше всего использовать приложение $ rootscope в приложении?

Я читал все, начиная от никогда, до его использования для хранения переменных, которые, как я предполагал, были предназначены для обмена данными между контроллерами. С тех пор я прочитал, что лучше использовать фабрики/службы для этого случая использования, и я также прочитал, что одним из допустимых вариантов использования является использование $ rootscope в качестве глобальной шины событий.

Я действительно не видел этого в документе Angularjs.

ответ

8

От ng-book:

Когда Угловая начинает работать и генерировать вид, она будет создавать привязку из корневого элемента нг-приложение к $ rootScope. Этот $ rootScope является потенциальным родителем всех объектов $ scope. Объект $ rootScope - это самый близкий объект, который мы имеем к глобальному контексту в Угловом приложении . Плохая идея приложить слишком много логики к этому глобальному контексту, в , так же, как не рекомендуется загрязнять глобальную область JavaScript.

Вы правы, вы должны обязательно использовать Services обмениваться данными и логикой между вашими модулями.

Ввод логики в ваш $ rootScope означает наличие плохой ремонтопригодности и модульности в вашем приложении, также очень сложно проверить проблемы.

я настоятельно рекомендую вам взглянуть на:

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

EDIT

Недавно я должен был принести некоторые элементы из API и поймать эти элементы, чтобы показать их в определенном виде. Механизм выбора элемента был в определенном Factory, тогда как механизм для форматирования и отображения элементов был в Controller.

Итак, я должен был выпустить событие в Factory, когда предметы были взяты и поймать это событие в Controller.

$ rootScope путь

//Factory 
$rootScope.$broadcast('refreshItems', items); 
//Controller 
$scope.$on('refreshItems', doSomething()); 

Он явно работал, но я действительно не хотел бы использовать $rootScope и я также заметил, что выполнение этой задачи были довольно несчастным.

Затем я попытался дать выстрел Postal.js:

Postal.js является в памяти шины сообщение - очень слабо вдохновлен AMQP - написан на JavaScript. Postal.js запускается в браузере или на сервере с использованием node.js. Это требует знакомой парадигмы «eventing-style» (из , которая известна большинству разработчиков JavaScript) и расширяет ее на , предоставляя «брокерские» и абонентские реализации, которые более сложнее, чем то, что вы обычно находите в простом событии испускания/агрегации.

Я попытался с помощью Postal.js для такого рода потребностей, и я узнал, что это на самом деле быстрее, чем при использовании $rootScope для этой цели.

//Factory 
$scope.$bus.publish({ 
        channel : 'reloadItems', 
        topic : 'reloadItems' 
        data : items 
); 

//Controller 
$scope.$bus.subscribe({ 
    channel : 'reloadItems', 
    topic : 'reloadItems', 
    callback : function() { 
    resetAndLoadItems(); 
    } 
}); 

Надеюсь, я был полезным.

+0

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

+0

Я понимаю, что вы имеете в виду. Ну, я думаю, что если вы действительно вынуждены реорганизовать приложение, вам нужно написать отдельные модули для инкапсуляции различных логик. Это займет много времени! Если вы ищете лучшие практики для инкапсуляции логики в разные модули, просто взгляните на [Документация модулей] (https://docs.angularjs.org/guide/module). Я также предлагаю вам попробовать небольшую демонстрацию, чтобы понять, как работать с некоторыми отдельными модулями, с их соответствующими контроллерами, службами и областями и, в конце, начать рефакторинг. – AndreaM16

+0

Если у меня есть служба, которая часто используется во всем приложении, и мне нужно подключить к множеству контроллеров, есть ли лучший способ, чем вставлять ее в любой другой контроллер? сделать его доступным через $ rootScope? Немного новый для Advanced Angular Concepts. –

3

От Angluar docs: каждое приложение имеет единый корневой объем. Все остальные области видимости представляют собой потоки потомков корневой области. Области обеспечивают разделение между моделью и видом, с помощью механизма для просмотра модели изменений.

Конечно, это будет связано с вопросом мнения и стиля. Я, как правило, придерживаюсь стиля, очень близкого к John Papa's Angular Style Guide.

В соответствии с этими двумя принципами, а также после хорошего разделения проблем, моя архитектура содержит фабричные модели, которые совместно используются в приложении. Мои контроллеры, в свою очередь, привязаны к службам, в которых хранятся общие данные.

Использование $ rootScope в качестве глобальной шины событий точно так же использует Angular. Должны ли вы пометить и сделать то же самое? Я не понимаю, почему нет. Но если да, убедитесь, что цель четко определена и, возможно, даже использует вашу собственную службу для регистрации событий на глобальной шине событий. Таким образом, вы отключите свое приложение от Angular, и если вы когда-нибудь решите, что хотите изменить структуру, в которой живет ваша глобальная шина событий, вы можете изменить ее в одном месте.

Это то, что я предлагаю:

автобус

// Angular specific: add service to module 
angular.module('app').factory('globalEventBus', GlobalEventBus); 

// Angular specific: inject dependencies 
GlobalEventBus.$inject(['$rootScope']); 

// Non framework specific. 
// param: fameworkEventBus will be $rootScope once injected 
function GlobalEventBus(fameworkEventBus) { 

    var globalEventBus = this; 

    globalEventBus.registerEvent(params...){ 
    fameworkEventBus. 
    } 

    return globalEventBus; 
} 

Глобальные модели данных Глобальные события

Мои модели данных умные и, как правило, содержат функции, которые предоставляют информацию о себе или получить/вернуть конкретные данные.

// Angular specific: add service to module 
angular.module('app').factory('dataModel', DataModel); 

function DataModel() { 

    var dataModel= this; 

    dataModel.myData = {}; 

    dataModel.GetSpecificData = funtion(param){ 
    return ... 
    } 

    return dataModel; 
} 

Контроллер

// Angular specific 
angular.module('app').controller('MyController', MyController); 

// Angular specific: inject dependencies to controller 
MyController.$inject = ['dataModel']; 

// By convention I use the same parameter name as the service. 
// It helps me see quickly if my order of injection is correct 
function MyController(dataModel) { 

    var myController = this; 

    // Bind to the service itself, and NOT to the service data property 
    myController.myData = dataModel; 

    myController.doStuff = function(){ 
    } 
} 

Here весело сообщение о привязке к услугам, а не обслуживать свойства.

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

+0

Не могли бы вы уточнить, как используется fameworkEventBus? – Augustas

0

После этого еще несколько работ с угловыми и больше чтения я нашел это основное правило для использования $ rootscope, что я хотел добавить другие ответы:

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