AngularJS - привязка/отслеживание функции, которая возвращает обещание

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

Angular позволяет вам поместить обещание (или что-либо с функцией .then(...)) в вашу область видимости, и как только оно будет разрешено, все $watches и все, что связано с этим обещанием, будет использовать разрешенное значение. Проблема возникает, когда вы используете функцию для возврата промиса, поскольку то же самое не применяется — она обрабатывается как простой объект.

Например:

var helloDef = $.Deferred();
$scope.hello = helloDef.promise();

$scope.getHello = function() {
    return $scope.hello;
};

$timeout(function() {
    helloDef.resolve('Hello!');
}, 1000);

Скрипка

Здесь использование ng-bind="hello" работает нормально и выводит Hello!, но ng-bind="getHello()" выводит [object Object], так как внутренний $watch возвращает объект обещания. Аналогично работает с $q вместо $.Deferred.

В моем реальном коде я создаю обещание при первом вызове функции, поэтому я не могу просто предварительно сделать обещание и ссылаться на него в области видимости.

Мне это также нужно не только для ng-bind, поэтому создание моей собственной директивы привязки, которая правильно обрабатывает этот случай, нецелесообразно.

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

Спасибо.

ОБНОВЛЕНИЕ: запрос на вытягивание: https://github.com/angular/angular.js/pull/3605

ОБНОВЛЕНИЕ 2: для дальнейшего использования автоматическая распаковка промисов устарела в ветке 1.2.


person Jussi Kosunen    schedule 12.08.2013    source источник
comment
ng-bind принимает выражение, а не функцию. это определяется модулем $parse.   -  person zs2020    schedule 12.08.2013
comment
Вызовы функций являются допустимыми выражениями, вы просто не можете использовать их в двусторонней привязке. Если бы getHello() возвращал строку вместо обещания, все бы работало нормально.   -  person Jussi Kosunen    schedule 13.08.2013


Ответы (2)


Для некоторых вещей я использую $resource. Если мне нужно дождаться этого, $then работает хорошо:

var r = $resource...get...
var p = r.$then...

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

person John Tseng    schedule 13.08.2013
comment
К сожалению, я использую механизм объединения запросов, который несовместим с тем, как $resource делает запросы. - person Jussi Kosunen; 13.08.2013

Pull request объединен, это должно быть исправлено в 1.2.0, поэтому я отмечу это как ответ.

person Jussi Kosunen    schedule 16.08.2013
comment
Как упоминалось в самом обновлении вопроса, эта функция была удалена до выхода стабильной версии 1.2. - person Ondrej Machulda; 08.12.2013