Angular ui-router通过resolve获取异步数据

时间:2013-08-01 20:51:08

标签: angularjs angular-ui angular-ui-router

我想显示一个包含与编辑项目对应的数据的表单。我使用ui-router进行路由。我定义了一个州:

myapp.config(function($stateProvider) {

    $stateProvider.
    .state('layout.propertyedit', {
        url: "/properties/:propertyId",
        views : {
            "contentView@": {
                templateUrl : 'partials/content2.html', 
                controller: 'PropertyController'
            }
        }
    });

PropertyController中,我想将$scope.property设置为来自以下呼叫的数据(Google Cloud Endpoints):

    gapi.client.realestate.get(propertyId).execute(function(resp) {
        console.log(resp);
    });

我不知道是否可以使用resolve,因为数据是异步返回的。我试过了

    resolve: {
        propertyData: function() {
            return gapi.client.realestate.get(propertyId).execute(function(resp) {
                console.log(resp);
            });
        }
    }

第一个问题,propertyId未定义。你如何从propertyId获得url: "/properties/:propertyId"

基本上我想在$scope.property中将PropertyController设置为异步调用返回的resp对象。

编辑:

myapp.controller('PropertyController', function($scope, , $stateParams, $q) {

    $scope.property = {};

    $scope.create = function(property) {
    }

    $scope.update = function(property) {
    }

function loadData() {
    var deferred = $q.defer();

    gapi.client.realestate.get({'id': '11'}).execute(function(resp) {
        deferred.resolve(resp);
    });

    $scope.property = deferred.promise;
}

});

4 个答案:

答案 0 :(得分:53)

您需要阅读the docs for resolve。 Resolve函数是可注入的,您可以使用$stateParams从路由中获取正确的值,如下所示:

resolve: {
    propertyData: function($stateParams, $q) {
        // The gapi.client.realestate object should really be wrapped in an
        // injectable service for testability...

        var deferred = $q.defer();

        gapi.client.realestate.get($stateParams.propertyId).execute(function(r) {
            deferred.resolve(r);
        });
        return deferred.promise;
    }
}

最后,一旦解决了解析函数的值,就可以在控制器中注入:

myapp.controller('PropertyController', function($scope, propertyData) {

    $scope.property = propertyData;

});

答案 1 :(得分:1)

我认为您的控制器功能需要$stateParams参数,您可以从中获取propertyId。然后,您可以使用$q参数并创建承诺,使用以下内容设置$scope.property

var deferred = $q.defer();

gapi.client.realestate.get(propertyId).execute(function(resp) {
    deferred.resolve(resp);
});

$scope.property=deferred.promise;

以下description of using promises用于处理异步调用。

答案 2 :(得分:1)

尝试这种简单的方法以正确的方式使用解决方法

州代码:

//general rtc vars
var localConn = new webkitRTCPeerConnection({'iceServers':[{'url':'stun:stun.1.google.com:19302'}]});
var remoteConn = new webkitRTCPeerConnection({'iceServers':[{'url':'stun:stun.1.google.com:19302'}]});
//var mediaStream;
var channel;

//creates a stream from webcam
//@params function streamHandle(stream)
function initStream(streamHandle){
    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
    var constraints = {audio:true,video:true};
    navigator.getUserMedia(constraints, successStream, errorStream);
    //onSuccess and Error functions
    function successStream(stream){
        window.stream = stream;
        console.log('TreRTC: Local Stream-'+ stream.id);
        //mediaStream = stream;
        localConn.addStream(stream);    //not sure if these need to be added before
        remoteConn.addStream(stream);   //or if they can be added in the creatOffer(stream) function
        streamHandle(stream);    //gets inserted into createOffer function
    }
    function errorStream(error){
        console.log('navigator.getUserMedia error: ', error);
    }
}

//creates an offer to be sent
//@params Stream stream (from getusermedia)
//@return string offer
function createOffer(stream){
    console.log('TreRTC: Creating Offer');
    //localConn.addStream(stream);    //tried both ways from top and from internal
    //remoteConn.addStream(stream);

    localConn.createOffer(function (sessionDescription){
        localConn.setLocalDescription(sessionDescription);
    }, function(error){
        console.log('Error setting local description: '+error);
    });

    localConn.onicecandidate = function(iceEvt){
        console.log('TreRTC: ICE in');            //ice events firing (12 total)
        if(iceEvt.candidate === null){
            console.log('TreRTC: ICE gathered');    //never reaches to this point...
            var offer = {'type': localConn.localDescription.type,
                         'sdp': localConn.localDescription.sdp};
            offer = JSON.stringify(offer);
            console.log('TreRTC: Offer initialized');
            return offer;    //returns offer as a string
        }    //could also specify a callback
    }
}

在上面的代码中,我发送的是我在网址中发送的参数数据。例如,如果我这样发送.state('yourstate', { url: '/demo/action/:id', templateUrl: './view/demo.html', resolve:{ actionData: function(actionData, $q, $stateParams, $http){ return actionData.actionDataJson($stateParams.id); } }, controller: "DemoController", controllerAs : "DemoCtrl" }) 这个数字5将转到/demo/action/5服务,该服务根据id检索一些json数据。最后数据将存储到actionData您可以使用该名称直接在控制器中使用该服务

以下代码返回一些JSON数据,这些数据基于我在状态级别传递的id

actionData

答案 3 :(得分:0)

这个怎么样:

function PropertyController($scope, $stateParams) {
   gapi.client.realestate.get($stateParams.propertyId).execute(function(resp) {
     $scope.property = resp;
   });
}