Как использовать $ rootScope в Angular для хранения переменных?


218

Как я могу использовать $rootScopeдля хранения переменных в контроллере, к которому я хочу позже обратиться в другом контроллере? Например:

angular.module('myApp').controller('myCtrl', function($scope) {
  var a = //something in the scope
  //put it in the root scope
});

angular.module('myApp').controller('myCtrl2', function($scope) {
  var b = //get var a from root scope somehow
  //use var b
});

Как бы я это сделал?


1
Вы должны внедрить $ rootScope в контроллер и использовать его как простой javascript
Ajay Beniwal

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

11
@Steve: часто задаваемые вопросы Angular гласят: «Не создавайте сервис, единственная цель которого в жизни - хранить и возвращать биты данных». Это создаст слишком большую нагрузку на цикл $ digest ..
Марвен Трабелси,

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

2
хорошо, потому что это не для инъекций, вам понадобится шприц для этого ..
Xsmael

Ответы:


249

Переменные, установленные в корневой области, доступны для области контроллера через прототипное наследование.

Вот модифицированная версия демоверсии @ Nitish, которая показывает отношения немного яснее: http://jsfiddle.net/TmPk5/6/

Обратите внимание, что переменная rootScope устанавливается при инициализации модуля, а затем каждая из унаследованных областей получает свою собственную копию, которую можно установить независимо ( changeфункция). Кроме того, значение rootScope также может быть обновлено ( changeRsфункция в myCtrl2)

angular.module('myApp', [])
.run(function($rootScope) {
    $rootScope.test = new Date();
})
.controller('myCtrl', function($scope, $rootScope) {
  $scope.change = function() {
        $scope.test = new Date();
    };

    $scope.getOrig = function() {
        return $rootScope.test;
    };
})
.controller('myCtrl2', function($scope, $rootScope) {
    $scope.change = function() {
        $scope.test = new Date();
    };

    $scope.changeRs = function() {
        $rootScope.test = new Date();
    };

    $scope.getOrig = function() {
        return $rootScope.test;
    };
});

7
Плюс 1 за ... э-э ... на самом деле отвечает на вопрос ОП. (Хотя @MBielski и другие правы).
Рэп

Если я сделаю это $scope.test = 'Some value', будут ли $rootScope.testизменения также?
Аллен Линаток

@AllenLinatoc нет, это не два разных объекта, хотя область действия $rootScope глобальна (для всех контроллеров), но $scopeостается локальной для контроллера. Если вы используете $scope.testдва разных контроллера, знайте, что это две разные переменные, $rootScope.test будет ли
одна и

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

Сколько переменных корневых областей мы можем создать в приложении?
Джей

161

Обмен данными между контроллерами - это то, для чего фабрики / службы очень хороши. Короче, работает примерно так.

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

app.factory('items', function() {
    var items = [];
    var itemsService = {};

    itemsService.add = function(item) {
        items.push(item);
    };
    itemsService.list = function() {
        return items;
    };

    return itemsService;
});

function Ctrl1($scope,items) {
    $scope.list = items.list; 
}

function Ctrl2($scope, items) {
    $scope.add = items.add;
}

Вы можете увидеть рабочий пример в этой скрипке: http://jsfiddle.net/mbielski/m8saa/


49
+1 $rootScopeНе следует использовать для обмена переменными, когда у нас есть такие вещи, как услуги и фабрики.
jjperezaguinaga

74
Что ж, Angular FAQ говорит об этом в нижней части страницы: «И наоборот, не создавайте сервис, единственная цель которого в жизни - хранить и возвращать биты данных». См .: docs.angularjs.org/misc/faq
Ойтун

11
Это простой пример. Я считаю, что они говорят, что не имеют службы, которая появляется только в одном контроллере. Я не могу сосчитать, сколько мест сотрудники, которые разработали Angular, специально сказали, что сервисы являются официальным способом передачи данных между контроллерами. Осмотрите список рассылки, спросите различные угловые светильники и посмотрите, что вы получите. Могу также отметить, что ваша цитата находится внизу раздела под названием «$ rootScope существует, но его можно использовать для зла». Передача данных с одного контроллера на другой - зло.
MBielski

1
Но если вам нужно зациклить ваши элементы в двух разных представлениях / контроллерах, вам нужно сначала скопировать данные в контроллер, чтобы передать их представлению? (Я считаю, что это $ rootScope решен)
Томас Деко

1
Разработчик должен сам принять решение о том, следует ли использовать службу или быстро исправить rootScope, для некоторых вещей глобальная область видимости является удобной и удобной, и я думаю, именно это и пытаются сказать Angular Docs. Давайте сохраним искусство в программировании и не станем роботами для MVC бла-бла-бла полностью. Вы можете использовать вышеуказанный сервис и $ watch для переменной, если вам нужен один контроллер, чтобы знать об изменениях, однако, поскольку он стоит здесь, это не совсем связь между контроллерами.
приземлился

21
angular.module('myApp').controller('myCtrl', function($scope, $rootScope) {
   var a = //something in the scope
   //put it in the root scope
    $rootScope.test = "TEST";
 });

angular.module('myApp').controller('myCtrl2', function($scope, $rootScope) {
   var b = //get var a from root scope somehow
   //use var b

   $scope.value = $rootScope.test;
   alert($scope.value);

 //    var b = $rootScope.test;
 //  alert(b);
 });

DEMO


Так что в Angular вы обычно не используете var?
trysis

1
это зависит от состояния. если хотите показать в html, тогда вам нужно использовать иначе, вы можете использовать var
Nitish Kumar

О, сфера для DOM?
trysis

1
Это может быть поздно, но для любого позднего посетителя область видимости является связующим звеном между представлением и контроллером согласно документации AJS. область не имеет прямой ссылки на DOM. тогда что это делает? вот более подробные документы docs.angularjs.org/guide/scope
yantaq

9

я не вижу причин делать это $ scope.value = $ rootScope.test;

$ scope - это уже наследование прототипа от $ rootScope.

Пожалуйста, посмотрите этот пример

var app = angular.module('app',[]).run(function($rootScope){
$rootScope.userName = "Rezaul Hasan";
});

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


6

сначала сохраните значения в $ rootScope как

.run(function($rootScope){
$rootScope.myData = {name : "nikhil"}
})

.controller('myCtrl', function($scope) {
var a ="Nikhilesh";
$scope.myData.name = a;
});

.controller('myCtrl2', function($scope) {
var b = $scope.myData.name;
)}

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


3

Если это просто «доступ в другой контроллер», то для этого вы можете использовать угловые константы, преимущество в этом; Вы можете добавить некоторые глобальные настройки или другие вещи, которые вы хотите получить доступ через приложение

app.constant(‘appGlobals’, {
    defaultTemplatePath: '/assets/html/template/',
    appName: 'My Awesome App'
});

а затем получить к нему доступ, как:

app.controller(‘SomeController’, [‘appGlobals’, function SomeController(config) {
    console.log(appGlobals);
    console.log(‘default path’, appGlobals.defaultTemplatePath);
}]);

(не тестировал)

больше информации: http://ilikekillnerds.com/2014/11/constants-values-global-variables-in-angularjs-the-right-way/



1

Есть несколько способов достичь этого:

1. Добавить $rootScopeв .runметод

.run(function ($rootScope) {
    $rootScope.name = "Peter";
});

// Controller
.controller('myController', function ($scope,$rootScope) {
    console.log("Name in rootscope ",$rootScope.name);
    OR
    console.log("Name in scope ",$scope.name);
});

2. Создайте один сервис и получите доступ к нему на обоих контроллерах.

.factory('myFactory', function () {
     var object = {};

     object.users = ['John', 'James', 'Jake']; 

     return object;
})
// Controller A

.controller('ControllerA', function (myFactory) {
    console.log("In controller A ", myFactory);
})

// Controller B

.controller('ControllerB', function (myFactory) {
    console.log("In controller B ", myFactory);
})
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.