Я опубликовал проблему на 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.
getHello()
возвращал строку вместо обещания, все бы работало нормально. - person Jussi Kosunen   schedule 13.08.2013