2016-02-11 45 views
0

我一直試圖解決這個問題幾個小時,並試圖找到堆棧溢出和其他網站的工作解決方案,但目前爲止還沒有工作。無法將POST響應對象綁定到我的視圖

的問題

我建立一個遊記web應用程序,允許用戶登錄和查看他們的行程(例如一個客場之旅)。目前,我正在實施該功能,讓用戶可以在單獨的視圖中查看他們從旅程列表中選擇的特定旅程。我傳遞選定旅程的id並從MongoDB中檢索對象。我使用POST實現了這一點。它的工作原理是所選行程的_id在請求中傳遞,然後用於使用Model.findById標識文檔 - 然後響應產生數據。數據綁定到$ scope.selection。

但是,雖然$ scope.selection包含數據(當記錄到控制檯)時,我似乎無法將其綁定到視圖(稱爲view_journey)。意思是,只要我想訪問,例如selection.name在我的view_journey.html中,表達式或ng-bind留空。

app.js

$scope.viewJourneybyId = function(id) { 
    var selectOne = { _id : id }; 
    $http.post('http://localhost:8080/view_journey', selectOne). 
    success(function(data) { 
     $scope.selection = data; 
     $scope.$apply(); 
     console.log("POST found the right Journey"); 
     console.log($scope.selection); 
    }).error(function(data) { 
     console.error("POST encountered an error"); 
    })  
} 

server.js

app.post("/view_journey", function(request, response, next) { 
    Journeys.findById(request.body._id, function(error, selection) { 
     if (error) 
     response.send(error) 
     response.json({ message: 'Journey found!', selection }); 
     }); 
    }); 

的index.html

<tr ng-repeat="journey in journeys"> 
    <td> 
     <a href="#/view_journey" ng-click="viewJourneybyId(journey._id)"> 
     {{journey.name}}</a> 
    </td> 
    <td>...</td>  
</tr> 

view_journey.html

<div class="panel panel-default"> 
    <div class="panel-heading"> 
    <h2 ng-bind="selection.name"></h2> 
    <!-- For Debugging --> 
    ID <span ng-bind="selection._id"> 
    </div> 
    <div class="panel-body"> 
    <table class=table> 
     <caption>{{selection.desc}}</caption> 
     ... 
    </table> 
    </div> 
</div> 

反饋 這是我的堆棧溢出的第一個問題,所以也請告訴我,如果我我的措辭在可能被誤解的方式問題,以及是否不是我應該提供更多細節,例如控制檯輸出。謝謝;)

+0

index.html和view_journey.html如何相關?它看起來像你有一個角路由發射,如果這樣(通常)創建一個新的控制器實例與一個單獨的範圍,所以它可能是$ scope.selection真的是未定義的。嘗試將view_journey.html放在與index.html相同的模板中,以測試您的數據流。或者,您必須提供有關應用程序結構的更多信息。 – tokkov

+0

是的,我在我的app.js文件中設置了一個路徑,但是我只使用一個控制器(mainCtrl)作爲整個應用程序(是的,我知道,我應該儘快更改)...所以我不認爲這是問題。此外,以完全相同的方式設置的其他路線也可以訪問相似的數據集。 下面是路由和mainCtrl的完整app.js文件: [app.js](https://github.com/supernoir/travelogue/blob/master/app/scripts/app.js) 這裏是我的server.js [server.js](https://github.com/supernoir/travelogue/blob/master/app/server.js) –

+0

無論何時控制器連接到您的視圖,都會創建一個控制器的新實例有自己的範圍。即使您使用具有不同模板的相同控制器,每當路線發生火災時也會發生這種情況。這意味着你的數據實際上並不存在於新控制器的範圍內,除非你以某種方式將其放在那裏。通常這是通過工廠或服務完成的。我會仔細看看你的代碼,看看我能看到什麼。 – tokkov

回答

0

擺弄你的代碼後,我可以證實,當觸發路線時,你將得到一個新的,乾淨的範圍的控制器的新實例。這是AngularJS的預期行爲。

您可以通過添加一個簡單的日誌消息作爲控制器的第一行驗證這一點:

console.log($scope.selected); 

你會發現,它總是登出「未定義」,因爲該變量從未設置(內viewJourneyById )。如果您離開該登錄並測試代碼,您將在viewJourneyById中看到日誌激發,但隨後將view_journey.html模板加載到ng-view中並立即創建「未定義」,並創建mainCtrl的新實例。在新視圖加載之後存在「未定義」,表明控制器功能正在對路線改變再次執行。

有幾種方法可以解決這個問題。首先,您可以創建一個工廠或服務,將其注入到您的控制器中,並讓它爲您存儲數據。這實際上是他們存在的原因之一,即在控制器之間共享數據。

廠:

travelogueApp.factory('myFactory',function() { 
    return { 
     selected: null, 
     journeys: [] 
    }; 
}); 

控制器:

travelogueApp.controller('mainCtrl', ['$scope','$http','$location','myFactory', function ($scope, $http, $location, myFactory) { 
    // put it into the scope so the template can see it. 
    $scope.factory = myFactory; 

    // do other stuff 

    $scope.viewJourneybyId = function(id) { 
     var selectOne = { _id : id }; 
     $http.post('http://localhost:8080/view_journey', selectOne) 
      .success(function(data) { 
       $scope.factory.selection = data; 
       console.log("POST found the right Journey"); 
       console.log($scope.factory.selection); 
      }) 
      .error(function(data) { 
       console.error("POST encountered an error"); 
      })  
     } 
    }]); // end controller 

模板:

<div class="panel panel-default"> 
    <div class="panel-heading"> 
     <h2>{{factory.selection.name}}</h2> 
    </div> 
    <div class="panel-body"> 
     <table class=table> 
     <caption>{{factory.selection.desc}}</caption> 
     ... 
     </table> 
    </div> 
</div> 

更多或少一些這樣的事情。另一種方法是將旅程ID鏈接作爲查詢字符串的一部分,然後在控制器中檢查是否存在旅程ID,如果找到,則查找旅程。這將是一個啓動路由,加載控制器的新實例,然後在view_journey頁面上加載數據的情況。您可以在這樣控制器搜索查詢字符串參數:

var journey_id = $location.search().id; 

兩種方法都可行。工廠/服務方法允許您通過存儲一些數據來最大限度地減少Web服務調用。然而,那麼你必須開始考慮數據管理,所以你的應用程序中沒有陳舊的數據。查詢字符串方式是解決問題的最快方法,但意味着即使您只是在相同的兩頁之間來回切換,每個路由轉換都將等待Web服務調用。

+0

太棒了,這個作品!感謝一堆:) –

相關問題