2013-10-24 42 views
0

我有一個頁面,其中包含一個可以更改服務器上資源狀態的按鈕。一切都連接起來,工作正常。但我不得不求助於發送瀏覽器「回來」的服務器響應,因爲我不想爲動作url顯示新模板。AngularJS + Rails:獲取資源,但留在當前頁面

這似乎是一個典型的事情:請服務器做一些事情,然後獲取資源的當前狀態,並在當前模板中重新顯示它而不重新提取模板。

頁面上的標記是這樣的:

<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

看起來你似乎依靠路由來處理服務器上的模型更新,而不是通過角度的$資源服務來完成。這裏有一個快速和骯髒的:

相反的路由,調用一個函數,當用戶點擊:

<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 }); 
      }; 
     }; 


    } 
]); 
+0

這說明了很多。然而,如我所料,來自$ http.get的響應是200,並且沒有調用成功函數來刷新模型。 – pferrel

+0

我剛剛測試了一個空的200響應$ http.get(...),並調用了成功函數。你確定這是問題嗎? – redmallard

+0

糟糕,405,我固定。對於後人,我從你的回答中瞭解到,$ routeParams是一個用routeProvider中指定的路由的每個部分填充的對象。此外,將一個函數附加到一個點擊看起來首先在該函數名稱的作用域中。資源或$ http.get或其他動詞返回一個承諾。要查看返回的數據或觸發下一個http操作,需要附加get(或其他動詞)的「.success」方法的函數。你的例子展示瞭如何使用所有這些。 – pferrel