【问题标题】:Create a JSONP API in AngularJS & consume with jQuery在 AngularJS 中创建 JSONP API 并使用 jQuery
【发布时间】:2013-04-18 04:38:43
【问题描述】:

现在我已经用 JQuery 创建了一个 JS API,但我想知道它是否可以用 AngularJs 来完成。

例如,想象一个像下面这样的小 API:

var $myapi= $myapi|| {};
;(function($, window, document, undefined){
    _call_myapi_jsonp: function(params,controller,action,eventName){
    if (!params) params = {};

    var url = this.urls.base+"/"+controller+"/"+action+"?callback=?";
    if (params.callback)
        url = this.urls.base+"/"+controller+"/"+action+"?callback="+params.callback;
    url = url + "&_"+new Date();
    delete params.callback;
    $.ajax({
        url: url,
        data: params,
        crossDomain:true,
        dataType:'jsonp',
        cache:false,
        ajaxOptions: {cache: false},
        jsonp: params.callback?false:true,
        success:function(data,status){
            if (eventName && eventName!=""){
                $($myapi).trigger(eventName,data);
            }
        }
    });
},
    level: {
    list: function(params){
        params = params || {};
        params.max = params.max!=undefined?parseInt(params.max):$myapi.defaults.levels.max;
        params.page = params.page!=undefined?parseInt(params.page):$myapi.defaults.levels.page;
        params.showActives = params.showActives!=undefined?params.showActives:$myapi.defaults.levels.showActives;
            $myapi._call_myapi_jsonp(params,"level","listJSONP","myapi.level.list");
        },
        info: function(params){
            $myapi._call_myapi_jsonp(params,"level","showJSONP","myapi.level.info");
        }
    }
}

我一直在搜索 AngularJs 文档并在 Google 中搜索,但我还没有找到可以在 AngularJS 中编写 Jquery 代码的方法。 我想也许可以使用 $routeProvider 来完成,但我没有找到任何示例或文档说明如何使用 $routeProvider 在不显示模板或重定向到某个地方的情况下进行 jsonp 调用。

【问题讨论】:

    标签: jquery api angularjs jsonp angularjs-scope


    【解决方案1】:

    听起来你需要的是一项服务,类似于这里正在做的事情:

    Recommended way of getting data from the server

    http://jsfiddle.net/wpPhY/

    但包含$resource:

    http://docs.angularjs.org/api/ngResource.$resource

    这是查询 Twitter 的 JSONP 服务的基本示例(取自 http://egghead.io):

    JSFiddle 演示: http://jsfiddle.net/gavinfoley/DJ6da/

    angular.module('Twitter', ['ngResource']);
    
    angular.module('Twitter')
    .controller('TwitterCtrl', ['$scope', '$resource', function ($scope, $resource) {
        $scope.twitter = $resource('http://search.twitter.com/:action',
            {action:'search.json', q:'angularjs', callback:'JSON_CALLBACK'},
            {get:{method:'JSONP'}});
    
        $scope.doSearch = function () {
            $scope.twitterResult = $scope.twitter.get({q:$scope.searchTerm});
        };
    }]);
    

    此外,将 Breeze 与 Angular 结合使用也值得一看。我自己没有使用过它,但你可以用它创建一些非常酷的 CRUD 应用程序:

    http://www.breezejs.com/samples/todo-angular

    如果您希望通过 jQuery 访问在特定 Angular 控制器(或范围)内定义的函数或属性,请查看 Plnkr 和下面的代码。

    说实话,如果可能的话,我真的不会走这条路。最好从您的解决方案中完全删除 jQuery 并坚持使用 Angular。意思是编写您的 Angular API 或服务并使用 Angular 控制器/指令等来使用它。

    换句话说,如果你打算在你的应用程序中使用 Angular,那么就选择“all Angular”。不要试图与 jQuery 混搭。它只会减慢您的速度并使您的代码更难维护。

    完整的 Plnkr 演示: http://plnkr.co/edit/X5SfKD?p=preview

    HTML

    <!DOCTYPE html>
    <html data-ng-app="myApp">
      <head>
        <link rel="stylesheet" href="style.css">
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
        <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>
        <script src="myApp.js"></script>
        <script src="script.js"></script>
      </head>
      <body>    
        <div id="parent" data-ng-controller="ParentCtrl">     
            <span id="someSpan">This is {{name}}.</span>    
            <div id="child" data-ng-controller="ChildCtrl">This is {{name}}.</div>    
    
            Get latest tweet for: <input type="text" data-ng-model="twitterUser" />
    
            <button data-ng-click="getLatestAngularTwitterPost()">Get Tweet</button><br/><br/>
    
            Latest {{searchTerm}} Twitter post:
            <div>        
                <img id="twitterProfileImage" data-ng-src="{{profileImage}}" />
                <span data-ng-bind-html-unsafe="tweet" id="tweet"></span>
            </div>    
        </div>    
      </body>
    </html>
    

    Angular 应用 - myApp.js

    angular.module('myApp', []);
    
    angular.module('myApp')
    .controller('ParentCtrl', function ($scope,  $http) {
        $scope.name = "parent";    
        $scope.testFunc = function () {
            return "Test is working."
        };
        $scope.twitterUser = "AngularJS";
        $scope.tweet;
        $scope.profileImage;
        $scope.searchTerm;
    
        // Returns latest post on Twitter from AngularJS
        $scope.getLatestAngularTwitterPost = function (callbackFunc) {        
            $scope.searchTerm = $scope.twitterUser;        
            var url = "http://api.twitter.com/1/users/show.json";
    
            $http.jsonp(url, {
              params: {
                callback: 'JSON_CALLBACK',
                screen_name: $scope.twitterUser
              }
            })
            .success(function(data){
                if(callbackFunc){
                    console.log("Passing twitter results to callback: " + callbackFunc.name);
                    return callbackFunc(data);
                }
    
                $scope.tweet = data.status.text;
                $scope.profileImage = data.profile_image_url;          
            })
            .error(function() {
                $scope.tweet = "<strong>Error: could not make JSONP request to Twitter.</strong>"; 
            });
        };
    });
    
    angular.module('myApp')
    .controller('ChildCtrl', function ($scope) {
        $scope.name = "child";
    });
    

    jQuery - script.js

    // Ex. of how to call methods and update properties 
    // in Angular controllers, from jQuery
    $(function () {
        // Get Angular controller "ParentCtrl".
        // Could also use $('#someSpan').scope(); to get "ParentCntl" scope
        var $scopeParentCtrl = $('#parent').scope();
        // Get Angular controller "ChildCtrl".
        var $scopeChildCtrl = $('#child').scope();
    
        // Update the "name" property in Angular controller "ParentCtrl"
        $scopeParentCtrl.$apply(function(){
          $scopeParentCtrl.name = "Joe";
          console.log("Parent name changed to " + $scopeParentCtrl.name);
        });
    
        // Update the "name" property in Angular controller "ChildCtrl"
        $scopeChildCtrl.$apply(function(){
          $scopeChildCtrl.name = "Gavin";
          console.log("Child name changed to "+ $scopeChildCtrl.name);
        });
    
        // Call the "testFunc" function in Angular conroller "ParentCtrl"
        console.log($scopeParentCtrl.testFunc());
    
         // Call the JSONP function in Angular controller "ParentCtrl"
        $scopeParentCtrl.getLatestAngularTwitterPost(jsonpCallback);      
    });
    
    function jsonpCallback(data) {
        var $scopeParentCtrl = $('#parent').scope();
        $scopeParentCtrl.tweet = data.status.text;
        $scopeParentCtrl.profileImage = data.profile_image_url;
    }
    

    【讨论】:

    • 但是通过这种方式,您可以从例如 chrome 控制台调用这些函数吗?
    • 感谢您的回答,它更好地实现了我的想法。我知道我应该避免将 AngularJS 与 jQuery 混合,但我必须为第三方的集成提供接口,所以我不能告诉他们“使用 Angular”。
    • @Eylen:很高兴为您提供帮助。如果你仍然想用 jQuery 编写你的 API,你可以使用 $scope.apply(); 从 Angular 控制器/指令中调用它。请参阅此问题和答案:stackoverflow.com/questions/14716822/…。如果您使用代码设置 Plnkr 或 JSFiddle,如果可以的话,我很乐意为您提供帮助。
    • 感谢您的提示,但我想我仍然不明白...您如何从非角度的 js 脚本调用控制器中的角度方法?如果我有时间,我会尝试填充 jsfiddle 或 plunker
    • @bootload 是的,现在需要 OAuth,所以不必费心更新。该代码仍然回答了主要的 OP 问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-01
    • 2015-03-19
    • 1970-01-01
    • 1970-01-01
    • 2013-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多