Angularjs는 1.2에서 템플릿에 바인딩되지 않습니다.
1.2로 업그레이드한 후 서비스로부터 반환된 약속이 다르게 동작합니다.간단한 서비스 myDates:
getDates: function () {
var deferred = $q.defer();
$http.get(aGoodURL).
success(function (data, status, headers, config) {
deferred.resolve(data); // we get to here fine.
})......
이전 버전에서는 컨트롤러에서 다음 작업을 수행할 수 있었습니다.
$scope.theDates = myDates.getDates();
getDates에서 반환된 약속은 Select 요소에 직접 바인딩될 수 있습니다.이것으로 동작하지 않고 컨트롤러의 약속에 따라 콜백을 제공해야 합니다.그렇지 않으면 데이터가 바인딩되지 않습니다.
$scope.theDates = matchDates.getDates();
$scope.theDates.then(function (data) {
$scope.theDates = data; // this wasn't necessary in the past
아직 의사 말이 있어요.
$q 약속은 템플릿엔진에 의해 angular로 인식됩니다.즉, 템플릿에서는 스코프에 부가된 약속을 결과값으로 간주할 수 있습니다.
이전 버전의 Angular에서는 동작하고 있었습니다만, 1.2 RC3의 자동 바인딩은 모든 심플한 서비스에서 실패합니다.내가 뭘 잘못하고 있는지 생각해 봐
1.2.0-rc3에는 다음과 같은 변경이 있습니다.
AngularJS 1.2.0-rc3 farwish-twitch는 $compile 및 $animate에서 우선순위가 높은 많은 문제를 수정하고 1.2를 위한 길을 열어줍니다.또한 이 릴리스에서는 일부 중요한 변경사항이 도입되어 경우에 따라서는 지시문과 템플릿이 파손될 수 있습니다.변경 사항을 이해하고 필요한 경우 코드를 마이그레이션하는 방법을 알아보려면 changelog를 읽어보십시오.이 릴리스의 자세한 내용은 changelog를 참조하십시오.
변경 로그에 설명이 있습니다.
$140:
@Nenad에서 알 수 있듯이 약속은 더 이상 자동으로 참조되지 않습니다.이것은 지금까지 본 것 중 가장 기이한 결정 중 하나입니다.그것은, 내가 의지하고 있던 기능을 묵묵히 배제하기 때문입니다(그리고 그것은, 나에게 있어서, 각도의 특유한 판매 포인트 중 하나이며, 적은 것이 더 중요합니다).그래서 이걸 알아내는 데 시간이 꽤 걸렸어요.특히 $resource 프레임워크는 여전히 잘 작동하는 것 같기 때문입니다.게다가 이 또한 출시 후보입니다.만약 그들이 정말로 이것을 비난해야 한다면(그 주장들은 매우 미약하게 들림) 그들은 최소한 묵묵히 그것을 중단하기 전에 경고가 있었던 유예기간을 줄 수 있었을 것이다.보통은 각이 진 것에 매우 깊은 인상을 주지만, 이것은 큰 마이너스입니다.나는 이것이 실제로 되돌아간다고 해도 놀라지 않을 것이다, 비록 지금까지는 비교적 불평이 적은 것 같지만.
어쨌든 해결책은 뭐죠?
항상 then()을 사용하고 $scope를 then 메서드로 할당합니다.
function Ctrl($scope) { foo().then( function(d) { $scope.d = d; }); )
언랩 함수를 통해 값을 호출합니다.이 함수는 약속의 필드를 반환하고 이 필드를 then 메서드로 설정합니다.그러므로 그 약속이 해결되지 않는 한 그것은 정의되지 않을 것이다.
$rootScope.unwrap = function (v) { if (v && v.then) { var p = v; if (!('$$v' in v)) { p.$$v = undefined; p.then(function(val) { p.$$v = val; }); } v = v.$$v; } return v; };
다음과 같이 할 수 있습니다.
Hello {{ unwrap(world) }}.
이것은 http://plnkr.co/edit/Fn7z3g?p=preview 에서 온 것으로, 관련지어져 있는 이름은 없습니다.
세트
$parseProvider.unwrapPromises(true)
메시지와 함께 살 수 있는 삶을 살 수 있습니다$parseProvider.logPromiseWarnings(false)
다만, 다음의 릴리스에서는 기능이 삭제되는 경우가 있습니다.
하아, 40년 동안 스몰톡이 가진 건become
오브젝트 참조를 전환할 수 있는 메시지입니다.그럴 수도 있었던 약속들...
갱신:
어플리케이션을 변경한 결과, 일반적인 패턴은 꽤 잘 동작하고 있는 것을 알 수 있었습니다.
오브젝트 'x'가 필요하고 이 오브젝트를 리모트로 취득할 수 있는 방법이 있다고 가정합니다.그러면 먼저 캐시에서 'x'를 확인합니다.물건이 있으면 돌려드립니다.이러한 객체가 존재하지 않으면 실제 빈 객체를 만듭니다.유감스럽게도 이 경우 어레이인지 해시/개체인지 확인해야 합니다.이 오브젝트는 다음 콜에서 사용할 수 있도록 캐시에 저장합니다.그런 다음 리모트콜을 시작하고 콜백 시 리모트시스템에서 얻은 데이터를 작성한 오브젝트에 복사합니다.캐시에 의해 get 메서드에 대한 반복 호출이 같은 오브젝트에 대해 많은 리모트콜을 생성하지 않게 됩니다.
function getX() {
var x = cache.get('x');
if ( x == undefined) {
cache.put('x', x={});
remote.getX().then( function(d) { angular.copy(d,x); } );
}
return x;
}
또 다른 방법은 get 메서드에 오브젝트의 수신처를 지정하는 것입니다.
function getX(scope,name) {
remote.getX().then( function(d) {
scope[name] = d;
} );
}
언제든지 Common Angular 서비스를 만들고 오래된 약속의 작동 방식을 재현하는 언랩 방식을 넣을 수 있습니다.다음은 방법의 예를 제시하겠습니다.
var shared = angular.module("shared");
shared.service("Common", [
function () {
// [Unwrap] will return a value to the scope which is automatially updated. For example,
// you can pass the second argument an ng-resource call or promise, and when the result comes back
// it will update the first argument. You can also pass a function that returns an ng-resource or
// promise and it will extend the first argument to contain a new "load()" method which can make the
// call again. The first argument should either be an object (like {}) or an array (like []) based on
// the expected return value of the promise.
// Usage: $scope.reminders = Common.unwrap([], Reminders.query().$promise);
// Usage: $scope.reminders = Common.unwrap([], Reminders.query());
// Usage: $scope.reminders = Common.unwrap([], function() { return Reminders.query(); });
// Usage: $scope.reminders.load();
this.unwrap = function(result, func) {
if (!result || !func) return result;
var then = function(promise) {
//see if they sent a resource
if ('$promise' in promise) {
promise.$promise.then(update);
}
//see if they sent a promise directly
else if ('then' in promise) {
promise.then(update);
}
};
var update = function(data) {
if ($.isArray(result)) {
//clear result list
result.length = 0;
//populate result list with data
$.each(data, function(i, item) {
result.push(item);
});
} else {
//clear result object
for (var prop in result) {
if (prop !== 'load') delete result[prop];
}
//deep populate result object from data
$.extend(true, result, data);
}
};
//see if they sent a function that returns a promise, or a promise itself
if ($.isFunction(func)) {
// create load event for reuse
result.load = function() {
then(func());
};
result.load();
} else {
then(func);
}
return result;
};
}
]);
이것은 기본적으로 오래된 약속대로 작동하며 자동으로 해결됩니다.단, 두 번째 인수가 함수일 경우 값을 스코프에 새로고침할 수 있는 ".load()" 메서드를 추가하는 이점이 있습니다.
angular.module('site').controller("homeController", function(Common) {
$scope.reminders = Common.unwrap([], Reminders.query().$promise);
$scope.reminders = Common.unwrap([], Reminders.query());
$scope.reminders = Common.unwrap([], function() { return Reminders.query(); });
function refresh() {
$scope.reminders.load();
}
});
이것들은 좋은 답변이었습니다.각도로 업그레이드 했을 때, 약속의 자동 포장이 기능하지 않게 되었을 때, 문제를 찾는 데 도움이 되었습니다.
Peter Kriens와 중복되는 위험을 무릅쓰고, 나는 이 패턴이 나에게 효과가 있다는 것을 알게 되었다(이것은 단순히 유명한 사람들의 인용구를 한 페이지에 넣는 단순한 예다).
마이 컨트롤러:
angular.module('myModuleName').controller('welcomeController',
function ($scope, myDataServiceUsingResourceOrHttp) {
myDataServiceUsingResourceOrHttp.getQuotes(3).then(function (quotes) { $scope.quotes = quotes; });
}
);
마이 페이지:
...
<div class="main-content" ng-controller="welcomeController">
...
<div class="widget-main">
<div class="row" ng-repeat="quote in quotes">
<div class="col-xs-12">
<blockquote class="pull-right">
<p>{{quote.text}}</p>
<small>{{quote.source}}</small>
</blockquote>
</div>
</div>
</div>
...
언급URL : https://stackoverflow.com/questions/19472017/angularjs-promise-not-binding-to-template-in-1-2
'code' 카테고리의 다른 글
JS/jQuery TypeError: jQuery(...).datepicker는 함수가 아닙니다. (0) | 2023.03.14 |
---|---|
Oracle 스키마의 모든 콘텐츠 삭제 (0) | 2023.03.14 |
JSON.stringify 함수 (0) | 2023.03.09 |
Swift 4 Codable, 단일 루트 레벨 키로 객체를 디코딩하는 방법 (0) | 2023.03.09 |
반응 - TypeError: 정의되지 않은 속성 'props'를 읽을 수 없습니다. (0) | 2023.03.09 |