Як використовувати $ rootScope у Angular для зберігання змінних?


217

Як я можу $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 говорять: "не створюйте сервіс, єдиною метою якого в житті є зберігання та повернення бітів даних". Це призведе до надмірного навантаження на цикл
перебору

Якщо я не можу ввести контролери в сервіси, як я можу надіслати змінну з вашої служби іншому моєму контролеру? Я не бачу ніякого способу зробити це робочим ... оцінюю ваше розуміння тут ..
приземлився

2
ну, тому що його не можна вводити, для цього знадобиться шприц ..
Xsmael

Відповіді:


248

Змінні, встановлені в кореневій області, доступні області контролера за допомогою прототипного успадкування.

Ось модифікована версія демонстрації @ 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 буде однакова змінна у всіх контролерах
Xsmael

Я припускаю, що ви не хочете часто використовувати $ rootScope з тієї ж причини, коли б ви не використовували глобальні змінні іншими мовами?
Zypps987

Скільки змінних rootcope ми можемо створити в додатку?
Джей

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 існує, але це може бути використане для зла". Передача даних від одного контролера до іншого - це зло.
МБієльський

1
Але якщо вам потрібно зробити цикл, хоча ваші предмети у двох різних переглядах / контролерах, вам потрібно скопіювати дані спочатку в контролер, щоб надати їх перегляду? (Я вважаю, що це вирішено $ rootScope)
Томас Деко

1
Розробник повинен вирішити питання про те, чи слід використовувати службу або швидко виправити rootScope, для деяких речей глобальна сфера є зручною та зручною - і я думаю, що це намагаються сказати кутові документи. Дозволяє тримати мистецтво в програмуванні і не перетворюватися на роботів на MVC bla bla bla bla. Ви можете скористатися вищевказаною службою та $ 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 docs.angularjs.org/guide/scope
yantaq

9

я не знаходжу причин робити це $ range.value = $ rootScope.test;

$ range вже є спадкоємством прототипу від $ 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 є батьківським з усіх областей $, кожен $ range отримує копію $ rootScope даних, до яких ви можете отримати доступ, використовуючи сам $ range.


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.