Nice programing

Angular JS : 프라 미스에 바인딩하는 방법

nicepro 2020. 11. 17. 21:05
반응형

Angular JS : 프라 미스에 바인딩하는 방법


나는 약속을 견해에 묶으려고 노력하고 있습니다. 직접 할 수 있는지 모르겠지만 그게 제가하려는 것입니다. 내가 뭘 잘못하고 있는지 어떤 아이디어?

참고 : 소스는 시간 초과로 인해 약간 고안되었으며 정적 데이터를 사용하지만 코드를보다 쉽게 ​​진단하기위한 것입니다.

편집 : JSFiddle 페이지 : http://jsfiddle.net/YQwaf/27/

수정 : 솔루션 : 약속을 직접 바인딩 수 있다는 것이 밝혀졌습니다 . 원래 코드에 두 가지 문제가있었습니다.

  1. angular의 $ timeout 대신 setTimeout ()을 사용하는 것이 문제였습니다. Angular는 시간 제한이 트리거 될 때 UI를 새로 고쳐야한다는 것을 알지 못합니다 (setTimeout 내에서 $ scope. $ apply를 사용하여이 문제를 해결할 수도 있고 $ timeout을 사용할 수도 있습니다).
  2. promise를 반환 한 함수에 바인딩하는 것이 문제였습니다. 두 번째로 호출되면 또 다른 약속을합니다. 더 나은 방법은 범위 변수를 약속에 설정하고 필요한 경우에만 새 약속을 만드는 것입니다. (제 경우에는 국가 코드에서 $ scope. $ watch를 호출했습니다)

HTML :

<div ng:controller="addressValidationController">
    Region Code <select ng:model="regionCode" ng:options="r.code as r.name for r in getRegions()"/>
    Country Code<select ng:model="countryCode"><option value="US">United States</option><option value="CA">Canada</option></select>
</div>

JS :

function addressValidationController($scope, $q) {
    var regions = {
        US: [{code: 'WI',name: 'Wisconsin'}, {code: 'MN',name: 'Minnesota'}], 
        CA: [{code: 'ON',name: 'Ontario'}]
    };
    $scope.getRegions = function () {
        var deferred = $q.defer();
        setTimeout(function () {
            var countryRegions = regions[$scope.countryCode];
            console.log(countryRegions);
            if(countryRegions === undefined) {
                deferred.resolve([]);
            } else {
                deferred.resolve(countryRegions);
            }
        }, 1000);
        return deferred.promise;
    };
}

경고 :이 답변은 작성 당시 정확했지만 1.2부터 Angular 템플릿 엔진은 약속을 투명하게 처리하지 않습니다! - @ 말볼 리오

예, 템플릿 엔진 (및 표현식)은 약속을 투명하게 처리하지만 컨트롤러의 범위 속성에 약속을 할당하고 새 약속을 반환하는 함수를 매번 호출하지 않습니다 (나는 이것이 문제라고 생각합니다. 약속은 매번 반환됩니다).

JSFiddle : http://jsfiddle.net/YQwaf/36/

HTML :

<div ng:controller="addressValidationController">
    Region Code <select ng:model="regionCode" ng:options="r.code as r.name for r in regions"/>
    Country Code<select ng:model="countryCode"><option value="US">United States</option><option value="CA">Canada</option></select>
</div>

JS :

function addressValidationController($scope, $q, $timeout) {
    var regions = {
        US: [{
            code: 'WI',
            name: 'Wisconsin'},
        {
            code: 'MN',
            name: 'Minnesota'}],
        CA: [{
            code: 'ON',
            name: 'Ontario'}]
    };

    function getRegions(countryCode) {
        console.log('getRegions: ' + countryCode);
        var deferred = $q.defer();
        $timeout(function() {
            var countryRegions = regions[countryCode];
            if (countryRegions === undefined) {
                console.log('resolve empty');
                deferred.resolve([]);
            } else {
                console.log('resolve');
                deferred.resolve(countryRegions);
            }
        }, 1000);
        return deferred.promise;
    };

    $scope.regions = [];

    // Manage country changes:
    $scope.$watch('countryCode', function(countryCode) {
        if (angular.isDefined(countryCode)) {
            $scope.regions = getRegions(countryCode);
        }
        else {
            $scope.regions = [];
        }
    });
}​

As of Angular 1.2, you can't use promises in templates directly anymore.
Instead, you need to put the result into $scope inside then, like you normally would—no magic.

As a temporary workaround to get the old behavior, you can call

$parseProvider.unwrapPromises(true)

but this feature will be removed later on, so don't depend on it.


As of Angular 1.3 - $parseProvider.unwrapPromises(true) will no longer work.

Instead, you should unwrap the promises directly:

myApiMethod().then(function(value){
    $scope.item = value; 
});

Note that promise unwrapping will still work with ngResource as usual.


returning a reference to the scope variable holding the list should suffice.

function addressValidationController($scope,$timeout) {
    var regions = {
        US: [{code: 'WI',name: 'Wisconsin'}, {code: 'MN',name: 'Minnesota'}], 
        CA: [{code: 'ON',name: 'Ontario'}]
    };

    $scope._regions = [];

    $scope.getRegions = function () {

        $timeout(function () {
            var countryRegions = regions[$scope.countryCode];
            console.log(countryRegions);
            if(countryRegions === undefined) {
                $scope._regions = []
            } else {
                $scope._regions = countryRegions
            }
        }, 1000);

        return $scope._regions;
    };
}

참고URL : https://stackoverflow.com/questions/13033118/angular-js-how-to-bind-to-promises

반응형