$ q.all в модульном контроллере angular-ui разрешается рано после последовательного открытия / закрытия

0

В настоящее время у меня модальный (Angular-UI Modal), который при открытии впервые работает отлично. Однако, после того как я закрою его, а затем снова открою, все начинает немного странно.

Код:

(function () {
    'use strict';

    angular.module('app.modals').controller('personalizeNewsSubscriptionsModalCtrl', ['$scope', '$log', '$modalInstance', '$q', 'termStoreSvc', 'userNewsSubscriptionsSvc',
            function ($scope, $log, $modalInstance, $q, termStore, userSub) {
                //#region Variable declaration
                var allTopics = [],
                    userSubs = [],
                    subscriptions = new termStore('Manaaged Metadata Service', 'TS Today', 'Topic'),
                    userSubscriptions = new userSub('blackba');

                var allSubsLoaded = subscriptions.ready(function () {
                        allTopics = subscriptions.terms;
                    }),
                    userSubsLoaded = userSubscriptions.ready(function () {
                        userSubs = userSubscriptions.subscriptions;
                    });

                $log = $log.getInstance('app.modals.personalizeNewsSubscriptionsModalCtrl');
                //#endregion                

                $q.all([allSubsLoaded, userSubsLoaded]).then(function () {
                    // use allTopics and userSubs to create $scope.subscriptions
                    $scope.subscriptions = allTopics.map(function (obj) {
                        return {
                            Title: obj,
                            Selected: userSubs.indexOf(obj) !== -1
                        }
                    });
                    $log.debug('Subscriptions object loaded', $scope.subscriptions);
                });

                subscriptions.init();
                userSubscriptions.init();                

                $scope.close = function () {
                    $modalInstance.dismiss('cancel');
                }
            }]);
})();

allSubsLoaded и userSubsLoaded являются обещаниями. Чтобы понять, как это разрешено, здесь приведена упрощенная версия моих услуг

(function () {
    'use strict';

    angular.module('app.services.sharepoint')
        .factory('termStoreSvc', ['$log', '$q', function ($log, $q) {
            var self = undefined,
                deferred = $q.defer(),
                promise = deferred.promise;

            var termStoreSvc = function () {                
                self = this;

                self.init = init;
                self.ready = function (fn) {
                    return promise.then(fn);
                }
            };            

            function init() {
                $log.debug('Initializing');

                // do some stuff here                

                $log.debug('Initialized');
                deferred.resolve();
            };


            return termStoreSvc;
        }]);
})();

Когда я вызываю init, он выполняет некоторые действия, а затем разрешает скрытое обещание, которое я объявлял тогда, когда ready() используется с функцией обратного вызова, обратный вызов не будет выполняться до тех пор, пока не будет выполнен метод init().

По какой-то причине после того, как я открываю/закрываю его в первый раз и открываю второе/третье/и т.д. Время, $q.all({array of promises}) разрешает раньше. Любые идеи почему?

Пример кода для решения:

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

(function () {
    'use strict';

    angular.module('app.services.sharepoint')
        .factory('termStoreSvc', ['$log', '$q', function ($log, $q) {
            var self = undefined;

            var termStoreSvc = function () {                
                self = this;

                self.init = init;

                self.deferred = $q.defer();
                self.promise = self.deferred.promise;
                self.ready = function (fn) {
                    return self.promise.then(fn);
                }
            };            

            function init() {
                $log.debug('Initializing');

                // do some stuff here                

                $log.debug('Initialized');
                self.deferred.resolve();
            };


            return termStoreSvc;
        }]);
})();
  • 0
    На первый взгляд может показаться, что обещание на вашей фабрике должно быть внутри экземпляра, возвращаемого фабрикой, поскольку обещание будет обновляться каждый раз, когда вы получаете экземпляр. В противном случае каждый экземпляр, полученный вами с завода, будет ссылаться на одно и то же обещание, которое разрешается при первом открытии окна ... Я напишу пример, когда доберусь до машины и опубликую скрипку.
  • 0
    Я точно понимаю, что вы говорите, и это имеет смысл. Я сделаю это.
Показать ещё 1 комментарий
Теги:

2 ответа

1
Лучший ответ

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

1

Ну, как я это вижу, фабрики предназначены для возврата объектов, которые могут иметь функции как атрибуты, и я никогда не делал новый экземпляр фабрики (этот новый терминStore вещь). Похоже, вы положили обещание на стек памяти, который уже был разрешен в первый раз. Шаблон Singleton может мешать вашим намерениям.

  • 0
    Вот так все и получилось, мне просто нужно было включить переменные deferred и promise в возвращаемый объект, а не только внутри фабрики. Я собираюсь принять ответ Халли, так как она опубликовала это в качестве комментария за несколько минут до вас. Спасибо за направление, хотя.
  • 0
    В этом принципиальная разница между сервисами и фабриками - фабрики способны на new .

Ещё вопросы

Сообщество Overcoder
Наверх
Меню