2013-06-05 35 views
79

我期待在本地開發一個硬編碼的JSON文件。我的JSON文件如下(有效投入JSON驗證時):

{ 
    "contentItem": [ 
      { 
      "contentID" : "1", 
      "contentVideo" : "file.mov", 
      "contentThumbnail" : "url.jpg", 
      "contentRating" : "5", 
      "contentTitle" : "Guitar Lessons", 
      "username" : "Username", 
      "realname" : "Real name", 
      "contentTags" : [ 
       { "tag" : "Guitar"}, 
       { "tag" : "Intermediate"}, 
       { "tag" : "Chords"} 
      ],  
      "contentAbout" : "Learn how to play guitar!", 
      "contentTime" : [ 
       { "" : "", "" : "", "" : "", "" : ""}, 
       { "" : "", "" : "", "" : "", "" : ""} 
      ],   
      "series" :[ 
       { "seriesVideo" : "file.mov", "seriesThumbnail" : "url.jpg", "seriesTime" : "time", "seriesNumber" : "1", "seriesTitle" : "How to Play Guitar" }, 
       { "videoFile" : "file.mov", "seriesThumbnail" : "url.jpg", "seriesTime" : "time", "seriesNumber" : "2", "seriesTitle" : "How to Play Guitar" } 
      ] 
     },{ 
      "contentID" : "2", 
      "contentVideo" : "file.mov", 
      "contentThumbnail" : "url.jpg", 
      "contentRating" : "5", 
      "contentTitle" : "Guitar Lessons", 
      "username" : "Username", 
      "realname" : "Real name", 
      "contentTags" : [ 
       { "tag" : "Guitar"}, 
       { "tag" : "Intermediate"}, 
       { "tag" : "Chords"} 
      ],  
      "contentAbout" : "Learn how to play guitar!", 
      "contentTime" : [ 
       { "" : "", "" : "", "" : "", "" : ""}, 
       { "" : "", "" : "", "" : "", "" : ""} 
      ],   
      "series" :[ 
       { "seriesVideo" : "file.mov", "seriesThumbnail" : "url.jpg", "seriesTime" : "time", "seriesNumber" : "1", "seriesTitle" : "How to Play Guitar" }, 
       { "videoFile" : "file.mov", "seriesThumbnail" : "url.jpg", "seriesTime" : "time", "seriesNumber" : "2", "seriesTitle" : "How to Play Guitar" } 
      ] 
     } 
    ] 
} 

我已經得到我的控制器,工廠和HTML當JSON是在工廠內工作的硬編碼。但是,現在我已經用$ http.get代碼替換了JSON,它不起作用。我已經看到$ http和$資源的很多不同的例子,但不知道要去哪裏。我正在尋找最簡單的解決方案。我只是想爲ng-repeat和類似的指令提取數據。

廠:

theApp.factory('mainInfoFactory', function($http) { 
    var mainInfo = $http.get('content.json').success(function(response) { 
     return response.data; 
    }); 
    var factory = {}; // define factory object 
    factory.getMainInfo = function() { // define method on factory object 
     return mainInfo; // returning data that was pulled in $http call 
    }; 
    return factory; // returning factory to make it ready to be pulled by the controller 
}); 

任何和所有幫助表示讚賞。謝謝!

+1

它不起作用?它有什麼作用?它會拋出一個錯誤嗎? JavaScript控制檯中是否有輸出? –

+0

控制檯只是說「無法加載資源」,然後有console.json文件路徑。所以它不會由於某種原因加載它。我的工廠和JSON完全如您所見。當我將JSON硬編碼到工廠時,它可以正常工作。 – jstacks

+0

你用什麼作爲後端? NodeJs還是一個簡單的基於python的服務器或其他東西? – callmekatootie

回答

214

好了,這裏的東西尋找到一個列表:

1)如果你沒有運行任何類型的網絡服務器和剛剛與文件測試://index.html,那麼你很可能運行納入同源政策問題。請參閱:

https://code.google.com/archive/p/browsersec/wikis/Part2.wiki#Same-origin_policy

許多瀏覽器本地不承載的文件訪問其他本地託管的文件。 Firefox確實允許,但前提是你要加載的文件與html文件(或子文件夾)包含在同一個文件夾中。

2)$ http.get(返回成功,函數)已經分裂了結果對象爲您提供:

$http({method: 'GET', url: '/someUrl'}).success(function(data, status, headers, config) { 

所以它是多餘的調用與功能(響應成功)和返回response.data。

3)成功函數不返回給它傳遞函數的結果,所以這不會做你認爲它的作用:

var mainInfo = $http.get('content.json').success(function(response) { 
     return response.data; 
    }); 

這是更接近你打算什麼:

var mainInfo = null; 
$http.get('content.json').success(function(data) { 
    mainInfo = data; 
}); 

4),但你真正想做的事是返回的對象引用與將要填充的屬性時的數據加載,所以是這樣的:

theApp.factory('mainInfo', function($http) { 

    var obj = {content:null}; 

    $http.get('content.json').success(function(data) { 
     // you can do some processing here 
     obj.content = data; 
    });  

    return obj;  
}); 

mainInfo.content將從null開始,當數據加載時,它將指向它。

另外,您可以返回實際的諾言$ http.get回報和使用:

theApp.factory('mainInfo', function($http) { 
    return $http.get('content.json'); 
}); 

然後你就可以在異步計算在控制器中使用的值:

$scope.foo = "Hello World"; 
mainInfo.success(function(data) { 
    $scope.foo = "Hello "+data.contentItem[0].username; 
}); 
+26

嘿,這是一個迴應和價格相同的角度$ http課程 - 很好的答案! – Mat

+4

在4)中的解釋中,$ http.get()解決之前不會調用'return obj'嗎?只是問,因爲我認爲這是發生在我身上的事情。 – Pathsofdesign

+3

是的。但是,解析$ http.get()時調用的閉包會保留對'obj'的引用。它將填寫您可以使用的內容屬性。 –

4

這答案幫了我很多,並指出我在正確的方向,但什麼對我和希望其他人有效:

menuApp.controller("dynamicMenuController", function($scope, $http) { 
$scope.appetizers= []; 
$http.get('config/menu.json').success(function(data) { 
    console.log("success!"); 
    $scope.appetizers = data.appetizers; 
     console.log(data.appetizers); 
    });  
}); 
+6

你不應該在服務中做這樣的事嗎? – Katana24

+0

千萬不要在控制器中這樣做!壞!你應該把這寫成一項服務。雖然你稱之爲json值的方式沒有錯,但你應該有一個服務返回在控制器中沒有這樣做的承諾。從可重用性的角度來看,這太可怕了。例如,您每執行一次加載控制器就會執行$ http.get(),而在服務中調用緩存版本的調用。 – Downpour046

1

我大概有這些問題。我需要從Visual Studio 2013中調試AngularJs應用程序。

默認情況下,IIS Express限制訪問本地文件(如json)。

但是,第一:JSON有JavaScript語法。

第二:javascript文件是允許的。

所以:

  1. 命名JSON到JS(data.json->data.js)。

  2. 正確的負載指令($http.get('App/data.js').success(function (data) {...

  3. 負載腳本data.js到頁(<script src="App/data.js"></script>

接着使用加載的數據的通常的方式,它只是解決方法,當然。

18

我想注意的是接受答案的第四部分是錯的

theApp.factory('mainInfo', function($http) { 

var obj = {content:null}; 

$http.get('content.json').success(function(data) { 
    // you can do some processing here 
    obj.content = data; 
});  

return obj;  
}); 

上面的代碼作爲@Karl齊勒斯寫將失敗,因爲它接收數據之前obj將總是被返回(因此值將始終是null),這是因爲我們正在一個異步調用。

的類似的問題的細節在this post


在角討論,使用$promise應對獲取數據時要進行的異步調用。

最簡單的版本是

theApp.factory('mainInfo', function($http) { 
    return { 
     get: function(){ 
      $http.get('content.json'); // this will return a promise to controller 
     } 
}); 


// and in controller 

mainInfo.get().then(function(response) { 
    $scope.foo = response.data.contentItem; 
}); 

我不使用successerror是我剛剛從doc發現,這兩種方法已被棄用的原因。

$http傳統承諾方法的成功和錯誤已被棄用。改爲使用標準then方法。

+2

在工廠使用''return $ http.get('content.json');'',否則返回null。 – Francesco

+1

嘿,一個人擡頭。它的工作原因(與你的答案相反)是你返回一個對象的引用。成功函數也可以引用同一個對象。當ajax函數最終返回時,它會更新返回的原始對象中的「content」屬性。嘗試一下。 :-) –

+1

P.s. '.success'現在已被棄用。改用'.then'。 https://docs.angularjs.org/api/ng/service/$http – redfox05

1

++這對我有效。這是vanilla javascirpt和良好的使用情況下,如取消雜亂與ngMocks庫進行測試時:

<!-- specRunner.html - keep this at the top of your <script> asset loading so that it is available readily --> 
<!-- Frienly tip - have all JSON files in a json-data folder for keeping things organized--> 
<script src="json-data/findByIdResults.js" charset="utf-8"></script> 
<script src="json-data/movieResults.js" charset="utf-8"></script> 

這是您的javascript文件,其中包含JSON數據

// json-data/JSONFindByIdResults.js 
var JSONFindByIdResults = { 
    "Title": "Star Wars", 
    "Year": "1983", 
    "Rated": "N/A", 
    "Released": "01 May 1983", 
    "Runtime": "N/A", 
    "Genre": "Action, Adventure, Sci-Fi", 
    "Director": "N/A", 
    "Writer": "N/A", 
    "Actors": "Harrison Ford, Alec Guinness, Mark Hamill, James Earl Jones", 
    "Plot": "N/A", 
    "Language": "English", 
    "Country": "USA", 
    "Awards": "N/A", 
    "Poster": "N/A", 
    "Metascore": "N/A", 
    "imdbRating": "7.9", 
    "imdbVotes": "342", 
    "imdbID": "tt0251413", 
    "Type": "game", 
    "Response": "True" 
}; 

最後,任何地方的JSON數據工作在你的代碼

// working with JSON data in code 
var findByIdResults = window.JSONFindByIdResults; 

注: -這非常適合測試,並且即使karma.conf.js也接受這些文件來運行測試,如下所示。此外,我建議這隻適用於清除數據和testing/development環境。

// extract from karma.conf.js 
files: [ 
    'json-data/JSONSearchResultHardcodedData.js', 
    'json-data/JSONFindByIdResults.js' 
    ... 
] 

希望這會有所幫助。

++建立在這個答案https://stackoverflow.com/a/24378510/4742733

UPDATE

一個簡單的方法是爲我工作的頂部只是包括function的代碼的底返回的任何JSON

// within test code 
let movies = getMovieSearchJSON(); 
..... 
... 
... 
.... 
// way down below in the code 
function getMovieSearchJSON() { 
     return { 
     "Title": "Bri Squared", 
     "Year": "2011", 
     "Rated": "N/A", 
     "Released": "N/A", 
     "Runtime": "N/A", 
     "Genre": "Comedy", 
     "Director": "Joy Gohring", 
     "Writer": "Briana Lane", 
     "Actors": "Brianne Davis, Briana Lane, Jorge Garcia, Gabriel Tigerman", 
     "Plot": "N/A", 
     "Language": "English", 
     "Country": "USA", 
     "Awards": "N/A", 
     "Poster": "http://ia.media-imdb.com/images/M/[email protected]@._V1_SX300.jpg", 
     "Metascore": "N/A", 
     "imdbRating": "8.2", 
     "imdbVotes": "5", 
     "imdbID": "tt1937109", 
     "Type": "movie", 
     "Response": "True" 
    } 
}