AngularJS: привязать служебную переменную к значению в $scope контроллера

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

Изначально у меня было так настроено...

<service.js>
...
var url = 'www.my-backend.com';
this.val = [
    {
        name: 'undefined',
        isValid: false
    }
];
$http.get(url, {})
    .success (function (data) {
        this.val = data;
    })
    .error (function () {
        this.val =  [
            {
                name: 'error',
                isValid: false
            }
         ];
    });
...

А потом в моем контроллере...

<controller.js>
...
$scope.val = service.val
...

Однако это не сработало (val.name было «неопределенным»), предположительно потому, что service.val был привязан к $scope контроллера до того, как запрос get успел завершиться. Однако это, похоже, противоречит тому, что я прочитал здесь.

Следующее, что я сделал, это...

<service.js>
...
var url = 'www.my-backend.com';
this.valPromise = $http.get(url, {});
...

А потом в моем контроллере...

<controller.js>
...
$scope.val = [
    {
        name: 'undefined',
        isValid: false
    }
];
service.valPromise
    .success (function (data) {
        $scope.val = data;
    })
    .error (function () {
        $scope.val =  [
            {
                name: 'error',
                isValid: false
            }
         ];
    });
...

Это сработало, но мне это не понравилось. Я чувствую, что эта логика принадлежит сервису.

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

В идеале я действительно хотел бы выяснить, как заставить мою первую попытку работать (жестко привязать мою служебную переменную к моей области действия контроллера по ссылке), но если это не то, что действительно можно сделать в рамках Angular, я буду рад использовать какое-то watch поведение. Может ли кто-нибудь определить, что я делаю неправильно или почему моя служебная переменная не подключается должным образом к моему контроллеру?


person Dan Forbes    schedule 17.09.2014    source источник
comment
В ваших $http обратных вызовах this это не служба.   -  person a better oliver    schedule 17.09.2014
comment
Итак, каков правильный синтаксис?   -  person Dan Forbes    schedule 17.09.2014


Ответы (2)


В ваших $http обратных вызовах this это не служба. Вы найдете множество ответов о значении this на SO. Вам нужно обратиться к сервису через переменную.

Вторая проблема заключается в том, что this.val = data; присвоит сервису новое значение, но не изменит данные в области видимости, которая по-прежнему указывает на старый массив. Поэтому вам нужно скопировать новые данные в существующий массив.

var service = this;
$http.get(url, {})
.success (function (data) {
    angular.copy(data, service.val);
})
person a better oliver    schedule 17.09.2014
comment
Я проголосовал за ваш ответ, потому что он, казалось, указывал на ошибку, которую я совершал, но не похоже, что он решает проблему, хотя вы можете признать это в заключительной части своего ответа. По вашему предложению в моем сервисе я привязываю this к переменной service, а затем в своих обратных вызовах устанавливаю значение service.val. Я хочу использовать информацию, возвращаемую службой, для заполнения данных на странице, контролируемой моим контроллером, но когда эта страница загружается, name.val все еще «не определено», и поэтому на моей странице не отображается полезная информация. Я что-то упускаю? - person Dan Forbes; 17.09.2014
comment
@DanForbes Если вы используете его на своей странице, как {{val.name}}, то действительно не имеет значения, когда обновляется name. Как Вы этим пользуетесь? - person a better oliver; 17.09.2014
comment
Я не использую его как {{val.name}}. Я использую его для заполнения поля выбора: <select ng-options="val.name for val in vals/>". - person Dan Forbes; 17.09.2014
comment
@DanForbes Это имеет те же последствия. Но я упустил один очевидный момент и обновил вопрос. - person a better oliver; 17.09.2014
comment
Это работает отлично и именно то, что мне нужно. Спасибо, @zeroflagL! - person Dan Forbes; 20.09.2014

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

person rleffler    schedule 17.09.2014