AngularJS: Как передавать переменные между контроллерами?

У меня есть два контроллера Angular:

function Ctrl1($scope) {
    $scope.prop1 = "First";
}

function Ctrl2($scope) {
    $scope.prop2 = "Second";
    $scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}

Я не могу использовать Ctrl1 внутри Ctrl2, потому что он не определен. Однако если я попытаюсь передать его вот так ...

function Ctrl2($scope, Ctrl1) {
    $scope.prop2 = "Second";
    $scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}

Я получаю ошибку Кто-нибудь знает как это сделать?

Делает

Ctrl2.prototype = new Ctrl1();

Тоже не получается.

ПРИМЕЧАНИЕ. Эти контроллеры не вложены друг в друга.


person dopatraman    schedule 17.08.2012    source источник
comment
Способов много, но лучший - угловые. Всегда, когда мы используем фреймворк, это лучший способ использовать ее собственные методы для работы не забывайте об этом   -  person pejman    schedule 29.12.2016
comment
Я нашел этот блог очень полезным Блог   -  person Black Mamba    schedule 14.09.2017


Ответы (16)


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

Простой пример услуги:

angular.module('myApp', [])
    .service('sharedProperties', function () {
        var property = 'First';

        return {
            getProperty: function () {
                return property;
            },
            setProperty: function(value) {
                property = value;
            }
        };
    });

Использование службы в контроллере:

function Ctrl2($scope, sharedProperties) {
    $scope.prop2 = "Second";
    $scope.both = sharedProperties.getProperty() + $scope.prop2;
}

Это очень хорошо описано в этом блоге (Урок 2 и далее в специфический).

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

Пример: var property = { Property1: 'First' }; вместо var property = 'First';.


ОБНОВЛЕНИЕ. Чтобы (надеюсь) прояснить ситуацию, вот скрипка, которая показывает пример:

  • Binding to static copies of the shared value (in myController1)
    • Binding to a primitive (string)
    • Привязка к свойству объекта (сохраняется в переменной области видимости)
  • Binding to shared values that update the UI as the values are updated (in myController2)
    • Binding to a function that returns a primitive (string)
    • Привязка к свойству объекта
    • Двусторонняя привязка к свойству объекта
person Gloopy    schedule 17.08.2012
comment
В этом случае - как область действия Ctrl2 узнает, когда sharedProperties.getProperty () изменяет значение? - person OpherV; 03.04.2013
comment
Если вы хотите, чтобы ваш пользовательский интерфейс обновлялся каждый раз при изменении свойства, вы можете изменить both на функцию, и она будет вызываться / повторно оцениваться во время процесса дайджеста angular. См. Пример этой скрипки. Кроме того, если вы привязываетесь к свойству объекта, вы можете использовать его непосредственно в своем представлении, и он будет обновляться по мере изменения данных аналогично этот пример. - person Gloopy; 03.04.2013
comment
Если вы хотите обнаруживать изменения в вашем контроллере и реагировать на них, можно добавить функцию getProperty() в область видимости и использовать $ scope. $ Watch, как в этом примере. Надеюсь, эти примеры помогут! - person Gloopy; 03.04.2013
comment
Здесь возникает проблема, поскольку службы не должны иметь состояния. Хранить свойство внутри сервиса неправильно (но удобно). Я начал использовать $ cacheFactory для чтения и записи данных. Я использую почти идентичный сервис, что и Gloopy, но вместо сохранения состояния в сервисе теперь он находится в кеше. Сначала создайте службу кеширования: angular.module ('CacheService', ['ng']) .factory ('CacheService', function ($ cacheFactory) {return $ cacheFactory ('CacheService');}); Включите in в свой app.js, вставьте его в службу, используйте его так: return CacheService.get (key); или CacheService.put (ключ, значение); - person Jordan Papaleo; 01.10.2013
comment
@ Breck421, в первом примере в собственной документации Angular их служба уведомлений сохраняет msgs таким же образом . Кажется, что сервисы все-таки могут иметь состояние. - person adamdport; 05.06.2014
comment
Ты прав; Это было предположение октября, и с тех пор многое произошло. В то время я еще не знал, что служба angular является одноэлементной. В общем случае при программировании служба является поставщиком данных, а не хранителем состояния. - person Jordan Papaleo; 06.06.2014
comment
Предоставленная скрипка не работает - она ​​не обновляет 1-й контроллер. Также он смешивает переменную с функциями по непонятной причине - {{stringValue}} внутри 1-го шаблона, но {{stringValue()}} внутри 2-го! - person Dmitri Zaitsev; 09.08.2014
comment
@DmitriZaitsev скрипка пыталась продемонстрировать разные стили привязки к примитивам (вот почему первый контроллер не обновляется должным образом). Я попытался описать это в разделе «Обновление» внизу ответа. Надеюсь это поможет! - person Gloopy; 11.08.2014
comment
Ниже я опубликовал решение для создания глобальных переменных без создания службы, а вместо этого с использованием $ rootScope. - person Sanjeev; 30.08.2014
comment
@Gloopy Похоже, что добавить sharedprops.getVar (), чтобы убедиться, что у вас есть обновленная переменная (особенно, если вы добавляете ее к уже существующему контроллеру), требует много работы. Ближе всего у меня получилось назначить саму функцию, а затем вызвать $ scope.both (), но тогда мне все равно нужно добавить () повсюду в моем контроллере. Есть ли способ избежать добавления () в конце всего? - person Organiccat; 19.09.2014
comment
@Organiccat, если вы привязываетесь к свойствам объекта вместо примитивного типа, вам не придется везде добавлять () после того, как объект будет в вашей области видимости. См. этот пример, надеюсь, это поможет! - person Gloopy; 19.09.2014
comment
@Gloopy - кажется, много работы просто для того, чтобы поделиться свойством, что произойдет, если я захочу поделиться списком собственности? мы можем сделать там hashMap? любой пример? Благодарю . - person Jaxox; 04.12.2014
comment
Пытаюсь понять, как и почему в этом ответе используется .service вместо .factory, как описано в документации по Angular. Почему за этот ответ проголосовали так высоко, если в документации используется другой метод? - person pspahn; 07.04.2015
comment
как я могу настроить службу для каждого контроллера. (вместо конфигурации на уровне модуля) - person OMGPOP; 25.06.2015
comment
@Jaxox извините за поздний ответ, который вы можете привязать к хешу, см. этот пример. @pspahn Я читал о различиях, но все еще использую .service и .factory как взаимозаменяемые: | @OMGPOP можно уточнить? - person Gloopy; 25.06.2015
comment
Если вы хотите показать ценный пример, сначала покажите, как установить, прежде чем использовать get - person Gino; 20.03.2016

Я люблю иллюстрировать простые вещи простыми примерами :)

Вот очень простой Service пример:


angular.module('toDo',[])

.service('dataService', function() {

  // private variable
  var _dataObj = {};

  // public API
  this.dataObj = _dataObj;
})

.controller('One', function($scope, dataService) {
  $scope.data = dataService.dataObj;
})

.controller('Two', function($scope, dataService) {
  $scope.data = dataService.dataObj;
});

И здесь jsbin

А вот очень простой Factory пример:


angular.module('toDo',[])

.factory('dataService', function() {

  // private variable
  var _dataObj = {};

  // public API
  return {
    dataObj: _dataObj
  };
})

.controller('One', function($scope, dataService) {
  $scope.data = dataService.dataObj;
})

.controller('Two', function($scope, dataService) {
  $scope.data = dataService.dataObj;
});

И здесь jsbin


Если это слишком просто, вот более сложный пример

Также см. Ответ здесь для комментариев по соответствующим передовым методам

person Dmitri Zaitsev    schedule 09.08.2014
comment
Да, я согласен с тобой. Всегда старайтесь делать вещи проще. - person Evan Hu; 17.01.2015
comment
Какой смысл объявлять var _dataObj = {};, когда вы возвращаете прямую ссылку на него ..? Это не личное. В первом примере вы можете сделать this.dataObj = {};, а во втором return { dataObj: {} }; это бесполезное объявление переменной ИМХО. - person T J; 12.12.2015
comment
@TJ Дело в том, чтобы разделить эту переменную между другими компонентами. Это простой пример, иллюстрирующий концепцию совместного использования. Переменная является частной внутри блока, затем вы предоставляете ее как общедоступную переменную, используя раскрывающий шаблон. Таким образом, существует разделение ответственности между хранением переменной и ее использованием. - person Dmitri Zaitsev; 12.12.2015
comment
@DmitriZaitsev вы говорите простые примеры, но если вы не покажете должным образом, как использовать частное состояние, вы просто запутаете людей. В вашем примере нет частного состояния, пока вы возвращаете прямую ссылку. - person T J; 12.12.2015
comment
@TJ Я не вижу ничего непонятного. Приватная переменная может быть предоставлена ​​модулем. Не стесняйтесь писать лучший ответ. - person Dmitri Zaitsev; 12.12.2015
comment
@DmitriZaitsev в идеале модуль должен предоставлять методы для изменения частных переменных определенным образом. переменные в вашем примере указывают на объекты, а объекты передаются по ссылке в javascript. Если они прямо разоблачены, то какой смысл называть их частными ..? в приведенных примерах нет конфиденциальности, и вопрос не касается таких частных состояний. Тот факт, что вы используете слова общедоступный и частный в таком примере, где нет конфиденциальности, может смутить новичков. Хорошего дня. - person T J; 13.12.2015
comment
@TJ Вы проверили связанный пример? Это все есть. Обратите внимание на образец раскрытия - он объясняет, что означает частное и публичное. Это чисто архитектурная концепция, не имеющая отношения к деталям реализации. Вы можете раскрыть свои частные переменные напрямую или через аксессоры - архитектура останется прежней, как и терминология. - person Dmitri Zaitsev; 14.12.2015

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

Для этого вам нужно будет использовать Сервис или Фабрику.

Эти службы - это НАИЛУЧШАЯ ПРАКТИКА для обмена данными между невложенными контроллерами.

Очень хорошая аннотация по этой теме о совместном использовании данных - как объявлять объекты. Мне не повезло, потому что я попал в ловушку AngularJS еще до того, как прочитал об этом, и был очень разочарован. Так что позвольте мне помочь вам избежать этой неприятности.

Я прочитал из "ng-book: Полная книга по AngularJS", что AngularJS ng-модели, которые создаются в контроллерах как голые данные, НЕПРАВИЛЬНЫ!

Элемент $ scope должен быть создан следующим образом:

angular.module('myApp', [])
.controller('SomeCtrl', function($scope) {
  // best practice, always use a model
  $scope.someModel = {
    someValue: 'hello computer'
  });

А не так:

angular.module('myApp', [])
.controller('SomeCtrl', function($scope) {
  // anti-pattern, bare value
  $scope.someBareValue = 'hello computer';
  };
});

Это потому, что рекомендуется (ЛУЧШАЯ ПРАКТИКА), чтобы DOM (html-документ) содержал вызовы как

<div ng-model="someModel.someValue"></div>  //NOTICE THE DOT.

Это очень полезно для вложенных контроллеров, если вы хотите, чтобы ваш дочерний контроллер мог изменять объект из родительского контроллера ....

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

Допустим, у вас есть служба Factory, а в пространстве возврата есть объектA, который содержит объектB, содержащий объектC.

Если из вашего контроллера вы хотите ПОЛУЧИТЬ объект C в свою область видимости, будет ошибкой сказать:

$scope.neededObjectInController = Factory.objectA.objectB.objectC;

Это не сработает ... Вместо этого используйте только одну точку.

$scope.neededObjectInController = Factory.ObjectA;

Затем в DOM вы можете вызвать objectC из objectA. Это оптимальная практика для заводов, и, что наиболее важно, она поможет избежать неожиданных и не обнаруживаемых ошибок.

person AFP_555    schedule 24.06.2014
comment
Думаю, это хороший ответ, но его довольно сложно переварить. - person pspahn; 07.04.2015

Решение без создания службы с использованием $ rootScope:

Чтобы поделиться свойствами между контроллерами приложений, вы можете использовать Angular $ rootScope. Это еще один вариант поделиться данными, поместив так, чтобы люди знали об этом.

Предпочтительный способ поделиться некоторыми функциями между контроллерами - это службы, для чтения или изменения глобального свойства вы можете использовать $ rootcope.

var app = angular.module('mymodule',[]);
app.controller('Ctrl1', ['$scope','$rootScope',
  function($scope, $rootScope) {
    $rootScope.showBanner = true;
}]);

app.controller('Ctrl2', ['$scope','$rootScope',
  function($scope, $rootScope) {
    $rootScope.showBanner = false;
}]);

Использование $ rootScope в шаблоне (свойства доступа с $ root):

<div ng-controller="Ctrl1">
    <div class="banner" ng-show="$root.showBanner"> </div>
</div>
person Sanjeev    schedule 27.08.2014
comment
В этот момент вы используете переменные с глобальной областью видимости, что отклоняется от идеи AngularJS о локальной области видимости всего в своих различных структурах. Добавление файла глобальных переменных приведет к тому же результату и упростит поиск того, где переменная изначально определена. В любом случае, не предлагал. - person Organiccat; 19.09.2014
comment
@Organiccat - Я понимаю вашу озабоченность, и поэтому я уже упоминал, что предпочтительным способом будут услуги, без сомнения. Но ya angular также предоставляет такой способ. Вам решать, как вы хотите управлять своим глобальным бизнесом. У меня был сценарий, в котором этот подход сработал для меня лучше всего. - person Sanjeev; 19.09.2014

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

app.service('sharedProperties', function () {

    var hashtable = {};

    return {
        setValue: function (key, value) {
            hashtable[key] = value;
        },
        getValue: function (key) {
            return hashtable[key];
        }
    }
});
person Juan Zamora    schedule 15.07.2014
comment
Я также создал образец, используя службу для обмена данными между разными контроллерами. Надеюсь, вам понравится. jsfiddle.net/juazammo/du53553a/1 - person Juan Zamora; 30.08.2014
comment
Хотя это работает, обычно это синтаксис для .factory. .service следует использовать, если вы определяете свою службу как тип / класс согласно docs.angularjs.org/api/auto/service/$provide#service - person Dmitri Zaitsev; 02.09.2014
comment
Дмитрий, вы правы, однако ребята из Angular, с моей точки зрения, просто немного изменили мою концепцию между сервисами (фасадами) и фабриками .... ну да ладно .... - person Juan Zamora; 10.09.2014
comment
Если услуга предназначена для facades, тогда для чего factory? - person Dmitri Zaitsev; 10.09.2014
comment
И поправьте меня, если я ошибаюсь, службы предназначены для возврата чего-то, что может быть объектом или значением. Фабрики предназначены для создания объектов. Фасас, который на самом деле представляет собой набор функций, которые что-то возвращают, - это то, что я думал сервисы где. Включая вызов функций с фабрик. Опять же, я вхожу в основное представление о том, что это для меня, а не о том, что на самом деле является с точки зрения Angular. (Абстрактная фабрика dofactory.com/net/abstract-factory-design-pattern), а подход адаптера - это то, что я предлагаю как услугу - person Juan Zamora; 17.09.2014
comment
Проверьте шаблон адаптера здесь dofactory.com/net/adapter-design-pattern - person Juan Zamora; 17.09.2014

Я склонен использовать ценности, и я рад, если кто-нибудь обсудит, почему это плохая идея.

var myApp = angular.module('myApp', []);

myApp.value('sharedProperties', {}); //set to empty object - 

Затем введите значение в соответствии с услугой.

Установить в ctrl1:

myApp.controller('ctrl1', function DemoController(sharedProperties) {
  sharedProperties.carModel = "Galaxy";
  sharedProperties.carMake = "Ford";
});

и доступ из ctrl2:

myApp.controller('ctrl2', function DemoController(sharedProperties) {
  this.car = sharedProperties.carModel + sharedProperties.carMake; 

});
person Chilledflame    schedule 16.02.2016
comment
чем это отличается от использования службы? - person dopatraman; 16.02.2016

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

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

angular.module('myApp', [])

  .factory('MyService', function() {

    // private
    var value = 0;

    // public
    return {
      
      getValue: function() {
        return value;
      },
      
      setValue: function(val) {
        value = val;
      }
      
    };
  })
  
  .controller('Ctrl1', function($scope, $rootScope, MyService) {

    $scope.update = function() {
      MyService.setValue($scope.value);
      $rootScope.$broadcast('increment-value-event');
    };
  })
  
  .controller('Ctrl2', function($scope, MyService) {

    $scope.value = MyService.getValue();

    $scope.$on('increment-value-event', function() {    
      $scope.value = MyService.getValue();
    });
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp">
  
  <h3>Controller 1 Scope</h3>
  <div ng-controller="Ctrl1">
    <input type="text" ng-model="value"/>
    <button ng-click="update()">Update</button>
  </div>
  
  <hr>
  
  <h3>Controller 2 Scope</h3>
  <div ng-controller="Ctrl2">
    Value: {{ value }}
  </div>  

</div>

person Zanon    schedule 24.03.2016

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

Вот рабочий плункер: http://plnkr.co/edit/Q1VdKJP2tpvqqJL1LF6m?p=info

Сначала создайте свою службу, в которой будут храниться ваши общие данные:

app.factory('SharedService', function() {
  return {
    sharedObject: {
      value: '',
      value2: ''
    }
  };
});

Затем просто введите его в свои контроллеры и возьмите общие данные в своей области:

app.controller('FirstCtrl', function($scope, SharedService) {
  $scope.model = SharedService.sharedObject;
});

app.controller('SecondCtrl', function($scope, SharedService) {
  $scope.model = SharedService.sharedObject;
});

app.controller('MainCtrl', function($scope, SharedService) {
  $scope.model = SharedService.sharedObject;
});

Вы также можете сделать это для своих директив, он работает таким же образом:

app.directive('myDirective',['SharedService', function(SharedService){
  return{
    restrict: 'E',
    link: function(scope){
      scope.model = SharedService.sharedObject;
    },
    template: '<div><input type="text" ng-model="model.value"/></div>'
  }
}]);

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

person Fedaykin    schedule 21.02.2015

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

person Noahdecoco    schedule 14.07.2014
comment
Вы могли бы сделать это с помощью служб или фабрик - Как ..? Как это сделать - это то, о чем спрашивает OP ... пожалуйста, опубликуйте полный ответ в самом stackoverflow, а не ссылайтесь на внешние ресурсы, ссылки могут перестать работать сверхурочно. - person T J; 12.12.2015

Не могли бы вы также сделать свойство частью родительского элемента области действия?

$scope.$parent.property = somevalue;

Я не говорю, что это правильно, но это работает.

person SideFX    schedule 15.05.2014
comment
Автор заявил, что NOTE: These controllers are not nested inside each other.. Если бы это были вложенные контроллеры или контроллеры с одним и тем же родителем, это сработало бы, но мы не можем этого ожидать. - person Chris Foster; 31.05.2014
comment
Как правило, полагаться на $parent, если этого можно избежать, - плохая практика. Хорошо спроектированный компонент многократного использования не должен знать о своих родителях. - person Dmitri Zaitsev; 02.09.2014

Ах, есть немного этого нового в качестве альтернативы. Это локальное хранилище и работает там, где работает angular. Пожалуйста. (Но правда, спасибо парню)

https://github.com/gsklee/ngStorage

Определите свои настройки по умолчанию:

$scope.$storage = $localStorage.$default({
    prop1: 'First',
    prop2: 'Second'
});

Доступ к значениям:

$scope.prop1 = $localStorage.prop1;
$scope.prop2 = $localStorage.prop2;

Сохраните значения

$localStorage.prop1 = $scope.prop1;
$localStorage.prop2 = $scope.prop2;

Не забудьте добавить ngStorage в ваше приложение и $ localStorage в ваш контроллер.

person kJamesy    schedule 10.09.2014
comment
Это решает другую проблему - постоянное хранилище. Это не масштабируемое решение рассматриваемой проблемы, поскольку оно приводит к утечке кода из-за побочных эффектов, таких как изменение объекта локального хранилища с уязвимостью конфликта имен среди других. - person Dmitri Zaitsev; 12.12.2015

Есть два способа сделать это

1) Используйте сервис get / set

2) $scope.$emit('key', {data: value}); //to set the value

 $rootScope.$on('key', function (event, data) {}); // to get the value
person Rohan Kawade    schedule 24.11.2015
comment
Это было моим решением. Спасибо. - person ivahidmontazer; 04.07.2021

Второй подход:

angular.module('myApp', [])
  .controller('Ctrl1', ['$scope',
    function($scope) {

    $scope.prop1 = "First";

    $scope.clickFunction = function() {
      $scope.$broadcast('update_Ctrl2_controller', $scope.prop1);
    };
   }
])
.controller('Ctrl2', ['$scope',
    function($scope) {
      $scope.prop2 = "Second";

        $scope.$on("update_Ctrl2_controller", function(event, prop) {
        $scope.prop = prop;

        $scope.both = prop + $scope.prop2; 
    });
  }
])

HTML:

<div ng-controller="Ctrl2">
  <p>{{both}}</p>
</div>

<button ng-click="clickFunction()">Click</button>

Подробнее см. Плункер:

http://plnkr.co/edit/cKVsPcfs1A1Wwlud2jtO?p=preview

person Codiee    schedule 08.03.2016
comment
Работает, только если Ctrl2 (слушатель) является дочерним контроллером Ctrl1. Контроллеры-близнецы должны связываться через $rootScope. - person herzbube; 19.05.2018

Я просмотрел ответы выше, я рекомендую предложение Педжмана 29 декабря '16 в 13:31, но он / она не оставил полного ответа. Вот он, я обозначу это как - ›(вам нужен сервис и слушатель $ watch на одной из областей от контроллеров для изменений в области обслуживания)

var app = 
angular.module('myApp', ['ngRoute', 'ngSanitize']);

app.service('bridgeService', function () {
    var msg = ""; 
    return msg;
});
app.controller('CTRL_1'
, function ($scope, $http, bridgeService) 
{
    $http.get(_restApi, config)
    .success(
    function (serverdata, status, config) {
        $scope.scope1Box = bridgeService.msg = serverdata;
    });
});
app.controller('CTRL_2'
, function ($scope, $http, bridgeService) 
{
    $scope.$watch( function () {
        return (bridgeService.msg);
    }, function (newVal, oldVal) {
        $scope.scope2Box = newVal;
    }, true
    );
});
person Jenna Leaf    schedule 04.09.2020

Если вы не хотите оказывать услуги, вы можете сделать это так.

var scope = angular.element("#another ctrl scope element id.").scope();
scope.plean_assign = some_value;
person thanksnote    schedule 01.03.2013
comment
Я не сомневаюсь, что этот ответ работает, но хочу отметить, что это противоречит философии AngularJS, согласно которой никогда не было объектов DOM в коде вашей модели / контроллера. - person JoeCool; 03.10.2013
comment
-1, потому что связь контроллера через DOM, на мой взгляд, плохая практика. - person Chris Foster; 31.05.2014
comment
@ChrisFoster, то, что молоток продается как инструмент, не означает, что его нельзя использовать в качестве пресс-папье. Я уверен, что для каждого фреймворка или инструмента вы всегда найдете разработчиков, которым необходимо составить список лучших практик. - person Andrei V; 22.08.2014
comment
@AndreiV - Плохая аналогия, нет недостатка в использовании молотка в качестве пресс-папье. Подобная плохая практика имеет явные недостатки и может легко привести к созданию спагетти-кода. Приведенный выше код хрупок, потому что теперь он зависит от того, где находится ваш контроллер в DOM, и его очень сложно протестировать. Использование службы - это лучшая практика по какой-то причине, потому что она не привязывает вашу реализацию к вашему шаблону. Я согласен с тем, что разработчикам часто приходится изменять список передовых практик, но не тогда, когда есть четкие, общие и более модульные передовые методы, которые работают лучше. - person Chris Foster; 22.08.2014

Помимо $ rootScope и сервисов, существует чистое и простое альтернативное решение для расширения angular для добавления общих данных:

в контроллерах:

angular.sharedProperties = angular.sharedProperties 
    || angular.extend(the-properties-objects);

Эти свойства принадлежат объекту angular, отделенному от областей видимости и могут использоваться совместно с областями действия и службами.

Преимущество 1 в том, что вам не нужно вводить объект: они доступны в любом месте сразу после вашего определения!

person williamjxj    schedule 13.07.2015
comment
Это похоже на наличие глобальных переменных по всему объекту window ... Если вы собираетесь загрязнять angular, почему бы просто не пойти дальше и не загрязнить объект окна ... - person T J; 12.12.2015