AngularJS + Rails:获取资源但保持当前页面

时间:2013-10-24 20:17:38

标签: ruby-on-rails angularjs

我有一个带有按钮的页面,该按钮将更改服务器上资源的状态。一切都很好,工作正常。但我不得不求助于服务器响应,将浏览器“返回”,因为我不想为动作网址显示新模板。

这似乎是一个典型的事情:要求服务器做某事,然后获取资源的当前状态,并在当前模板中重新显示它,而不重新获取模板。

页面上的标记如下:

<a ng-href="/api/preference/{{video._id}}/add_to_watchlist" data-method="get">
    <i rel="tooltip" data-original-title="Add to watchlist" class="icon-3x action-icon
        icon-plus-sign" ng-class="{iconSelected : video.user_watchlist == 1}">
    </i>
</a>

根据$ scope.video.watchlist的值突出显示图标。单击时,它会在服务器上触发自定义操作,以将正在查看的视频添加到当前用户的监视列表中。创建的网址是/api/preference/{{video._id}}/add_to_watchlist,这会触发服务器控制器,它执行正确的操作,但不会转到/api/preference/{{video._id}的模板。 / add_to_watchlist服务器响应告诉客户端在Rails中“返回”,这是redirect_to :back

显然,这是错误的。它可以工作,但重新获取整个页面标记和数据。

加载原始数据的AngularJS控制器位于:

GuideControllers.controller('VideoDetailCtrl', ['$scope', 'Video',
    function($scope, Video) {
        var pattern = new RegExp( ".*/([0-9,a-f]*)", "gi" );
        //ugh, there must be a better way to get the id!
        $scope.video = Video.get({ id: pattern.exec( document.URL )[1] });
    }
]);

这是获取json的资源

var VideoServices = angular.module('VideoServices', ['ngResource']);

VideoServices.factory('Video', ['$resource',
    function($resource){
        return $resource("/api/videos/:id", {id: "@id"}, {
            update: {method: "PUT"},
            query: {
                isArray: true,
                method: "GET",
                headers: {
                    "Accept": "application/json",
                    "X-Requested-With": "XMLHttpRequest"
                }
            },
            get: {
                isArray: false,
                method: "GET",
                headers: {
                    "Accept": "application/json",
                    "X-Requested-With": "XMLHttpRequest"
                }
            }
        });
    }
]);

不知怎的,我需要

  1. 告诉服务器add_to_watchlist而不更改浏览器URL
  2. 触发重新获取视频json而不重新加载模板。

1 个答案:

答案 0 :(得分:1)

您似乎依靠路由来处理服务器上的模型更新,而不是通过angular的$ resource服务来实现。这是一个快速和肮脏的:

而不是路由,在用户点击时调用函数:

<a ng-click="addToWatchlist(video._id)">
<i rel="tooltip" data-original-title="Add to watchlist" class="icon-3x action-icon
    icon-plus-sign" ng-class="{iconSelected : video.user_watchlist == 1}">
</i>
</a>

将点击处理程序功能添加到您的控制器(我在这里使用$ http,但您最好向视频资源添加自定义操作)。在成功回调中,您可以重新加载视频。或者,更好的是,您可以从add_to_watchlist操作返回视频。

查看http://docs.angularjs.org/tutorial/step_07解释$ routeParams(回答有关获取视频ID的评论)。

GuideControllers.controller('VideoDetailCtrl', ['$scope', '$http', '$routeParams', 'Video',
    function($scope, $http, $routeParams, Video) {
        $scope.video = Video.get({ id: $routeParams.videoId });
        $scope.addToWatchlist = function(videoId) {
            $http.get('/api/preference/'+videoId+'/add_to_watchlist').success(function() {
                $scope.video = Video.get({ id: $routeParams.videoId });
            };
        };


    }
]);