Angularjs, пропускаючи область дії між маршрутами


87

У мене ситуація з формою, яка розтягується на декілька сторінок (можливо, не ідеально, але саме так воно і є). Я хотів би мати одну область для всієї форми, яка заповнюється під час руху, так що якщо користувач рухається вперед-назад між кроками, легко запам'ятати стан.

Тому мені потрібно зробити в дуже псевдокоді:

  1. Встановити $scope.val = <Some dynamic data>
  2. Клацніть на посилання та перейдіть на новий шаблон (можливо, з тим самим контролером).
  3. $scope.val має мати те саме значення, що й на останній сторінці.

Чи якимось чином збережені дані для обсягу є правильним шляхом для цього, чи є інший шлях? Чи можете ви навіть створити контролер, який має постійний обсяг між маршрутами, крім збереження його в базі даних, звичайно.


Просто як доповнення до ganaraj: Тут ви знайдете справді приємний запис у блозі з екранізацією, як змусити різних контролерів спілкуватися. Є також кілька корисних jsfiddles, з якими можна пограти. onehungrymind.com/angularjs-communicating-between-controllers, сподіваюся, це допоможе.
F Lekschas

Відповіді:


138

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

Скажімо, ви хочете зберегти дані, що стосуються користувача

Ось як ви визначаєте послугу:

app.factory("user",function(){
        return {};
});

У вашому першому контролері:

app.controller( "RegistrationPage1Controller",function($scope,user){
    $scope.user = user;
    // and then set values on the object
    $scope.user.firstname = "John";
    $scope.user.secondname = "Smith";
});

app.controller( "RegistrationSecondPageController",function($scope,user){
        $scope.user = user;
        // and then set values on the object
        $scope.user.address = "1, Mars";

    });

6
Аааа! Я пробував це раніше, але не міг змусити його працювати, оскільки я використовував один і той же контролер для обох маршрутів, тому на кожному новому маршруті значення за замовчуванням переписували б ті, які я ввів на попередній сторінці. З двома контролерами або без стандартних значень це більше не відбувається. Дякую!
Ерік Хонн,

1
Що стосується Value Recipe docs.angularjs.org/guide/providers , як myApp.value('clientId', 'a12345654321x');це також зберігається між маршрутами?
The Bndr

@TheBndr: Має бути. Цінності - це лише особлива форма послуг, наскільки я розумію.
Роберт Коритник,

3
Служби не зберігатимуть дані, якщо ви перезавантажите сторінку ... Отже, якщо ви перебуваєте на сторінці 4 своєї форми та перезавантажуєте цю сторінку, ви втратите всі заповнені дані.
danielrvt

1
Приємна відповідь! Як допоміжний момент, керівництво стилем для тих, хто береться за цю відповідь - служби, які самі не є конструкторами (тобто використовуються як нові XX), слід називати верблюдом у нижньому регістрі: github.com/mgechev/angularjs-style-guide .
Matt Byrne

9

Послуга буде працювати, але логічним способом зробити це, використовуючи лише звичайні області та контролери, є налаштування контролерів та елементів так, щоб вона відображала структуру вашої моделі. Зокрема, вам потрібен батьківський елемент і контролер, які встановлюють батьківський обсяг. Окремі сторінки форми повинні знаходитись у поданні, яке є дочірнім для батьків. Батьківська область зберігається навіть під час оновлення дочірнього подання.

Я припускаю, що ви використовуєте ui-маршрутизатор, щоб ви могли мати вкладені іменні подання. Потім у псевдокоді:

<div ng-controller="WizardController">
  <div name="stepView" ui-view/>
</div>

Потім WizardController визначає змінні області, які ви хочете зберегти на етапах багатосторінкової форми (яку я називаю "майстром"). Тоді ваші маршрути оновлюватимуться stepViewлише. Кожен крок може мати власні шаблони, контролери та області, але їх сфери втрачаються від сторінки до сторінки. Але сфери застосування у WizardController зберігаються на всіх сторінках.

Щоб оновити обсяги WizardController від дочірніх контролерів, вам потрібно використовувати синтаксис типу $scope.$parent.myProp = 'value'або визначити функцію setMyPropв WizardController для кожної змінної області. В іншому випадку, якщо ви спробуєте встановити батьківські змінні області безпосередньо з дочірніх контролерів, ви в кінцевому підсумку просто створите нову змінну області для самого дочірнього елемента, затінюючи батьківську змінну.

Це важко пояснити, і я перепрошую за відсутність повного прикладу. В основному вам потрібен батьківський контролер, який встановлює батьківський обсяг, який буде збережений на всіх сторінках вашої форми.


1
Це може працювати з інтерфейсом користувальницького інтерфейсу так (і це досить приємний спосіб створити таку сторінку), але не з коробки. Нестандартний спосіб обслуговування - це шлях.
Ерік Хонн,

1
Тільки для уточнення, батьківські властивості області завжди успадковуються дочірньою областю. Однак, якщо ви хочете встановити батьківську властивість області з дочірньої області, вам потрібно отримати доступ до неї в батьківській, інакше ви створюєте нову властивість з тим самим іменем для дочірньої області. Встановлення батьківської властивості області можна зробити, пройшовши:$scope.$parent.myProp = 'hello world';
mbursill

1
Це набагато приємніший підхід, ніж використання послуги. Служби є єдиними, тому будь-який визначений там стан є загальним для програми. Якщо користувач частково вийде з майстра, а потім перезапустить його, у службі залишиться стан, що залишився від попереднього запуску - якщо ви не переконаєтесь, що правильно очищаєте службу в кожній точці виходу, але це цілком може легко стати значним головним болем в обслуговуванні!
Ден Кінг,

Набагато сильніше цієї відповіді
Курай Банкусу

Послуги - це перше, що спадає вам на думку, якщо ви не використовуєте Angular UI Router. Однак, якщо ви використовуєте маршрутизатор інтерфейсу, він має вкладені рішення, які можуть зберігати інформацію між вкладеними поданнями. Я думаю, що це був би більш чистий підхід, ніж спроба отримати доступ до батьківської області. medium.com/opinionated-angularjs/…
losmescaleros

5

Дані можуть передаватися між контролерами двома способами

  1. $rootScope
  2. Модель

Наведений нижче зразок демонструє передачу значень за допомогою моделі

app.js

angular.module('testApp')
  .controller('Controller', Controller)
  .controller('ControllerTwo', ControllerTwo)
  .factory('SharedService', SharedService);

SharedService.js

function SharedService($rootScope){

 return{
    objA: "value1",
    objB: "value2"
  }
}

// Змінюємо значення в контролері A

Controller.js

function Controller($scope, SharedService){

 $scope.SharedService = SharedService;

 $scope.SharedService.objA = "value1 modified";
}

// Доступ до значення в controllertwo

ControllerTwo.js

function ControllerTwo($scope, SharedService){

 $scope.SharedService = SharedService;

 console.log("$scope.SharedService.objA"+$scope.SharedService.objA); // Prints "value1 modified"
}

Сподіваюся, це допомагає.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.