AngularJS: โรงงาน $ http. รับไฟล์ JSON


84

ฉันต้องการพัฒนาในเครื่องด้วยไฟล์ 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 ถูกฮาร์ดโค้ดภายในโรงงาน อย่างไรก็ตามตอนนี้ฉันได้แทนที่ JSON ด้วยรหัส $ http.get แล้วก็ไม่ได้ผล ฉันได้เห็นตัวอย่างที่แตกต่างกันมากมายของทรัพยากร $ 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 หรือไม่?
Josh Lee

คอนโซลบอกเพียงว่า "Failed to load resource" จากนั้นมีพา ธ ไฟล์ console.json ดังนั้นจึงไม่โหลดด้วยเหตุผลบางประการ โรงงานและ JSON ของฉันตรงตามที่คุณเห็นด้านบน เมื่อฉันฮาร์ดโค้ด JSON ลงในโรงงานมันก็ใช้งานได้
jstacks

1
คุณใช้อะไรเป็นแบ็กเอนด์ของคุณ? NodeJs หรือเซิร์ฟเวอร์ที่ใช้ python แบบธรรมดาหรืออย่างอื่น?
callmekatootie

ฉันแค่พยายามพัฒนายกเว้นแบ็กเอนด์ (Rails) ดังนั้น JSON จึงเป็นเพียงไฟล์. json ที่มีข้อมูลอยู่เหนือฮาร์ดโค้ด คงจะคล้ายกับสิ่งที่แบ็กเอนด์จะแสดงผล
jstacks

คุณอาจไม่ต้องการ ".data" ในการตอบกลับ .. เปลี่ยนเป็น - "return response;" เว้นแต่ JSON ที่ส่งคืนของคุณจะรวมอยู่ในออบเจ็กต์ "data"
Bhaskara Kempaiah

คำตอบ:


218

โอเคนี่คือรายการสิ่งที่ต้องพิจารณา:

1) หากคุณไม่ได้ใช้งานเว็บเซิร์ฟเวอร์ใด ๆ และเพิ่งทดสอบกับ file: //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) {

ดังนั้นจึงซ้ำซ้อนที่จะเรียกความสำเร็จด้วย function (response) และ return 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;
});

27
นี่คือคำตอบและหลักสูตร $ http เชิงมุมในราคาเดียวกัน - คำตอบที่ดี!
จ้า

4
ในคำอธิบายของคุณภายใต้ 4) จะไม่เรียก 'return obj' ก่อนที่ $ http.get () จะได้รับการแก้ไขหรือไม่? แค่ถามเพราะฉันคิดว่านั่นคือสิ่งที่เกิดขึ้นกับฉัน
Pathsofdesign

3
ใช่! ฉันจะ. แต่การปิดที่เรียกเมื่อ $ http.get () ได้รับการแก้ไขจะยังคงอ้างอิงถึง "obj" มันจะกรอกคุณสมบัติเนื้อหาที่คุณสามารถใช้ได้
Karen Zilles

อะไรคือปัญหาในการใช้รูปแบบที่สองของ # 3 มากกว่าการใช้ # 4
Spencer

1
การโทรกลับที่ถูกล่ามโซ่ .success () เลิกใช้งานแล้ว ใช้. แล้ว (สำเร็จข้อผิดพลาด) แทน
Timothy Perez

21

ผมอยากจะทราบว่า หนึ่งในสี่ได้รับการยอมรับคำตอบที่ไม่ถูกต้อง

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 Zilles เขียนจะล้มเหลวเนื่องจากobjจะถูกส่งกลับก่อนที่จะได้รับข้อมูลเสมอ (ดังนั้นค่าจะเป็นเสมอnull) และนี่เป็นเพราะเรากำลังทำการโทรแบบอะซิงโครนัส

รายละเอียดของคำถามที่คล้ายกันจะกล่าวถึงในโพสต์นี้


ใน Angular ใช้$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;
});

เหตุผลที่ฉันไม่ใช้successและerrorเพิ่งค้นพบจากเอกสารทำให้สองวิธีนี้เลิกใช้แล้ว

$httpความสำเร็จวิธีการดั้งเดิมสัญญาและข้อผิดพลาดได้รับการคัดค้าน ใช้thenวิธีมาตรฐานแทน


2
ใช้return $http.get('content.json');ในโรงงานมิฉะนั้นผลตอบแทนจะเป็นโมฆะ
Francesco

2
เฮ้แค่หัวขึ้น เหตุผลที่ใช้งานได้ (ตรงข้ามกับคำตอบของคุณที่นี่) คือคุณกำลังส่งคืนการอ้างอิงไปยังวัตถุ ฟังก์ชันความสำเร็จยังมีการอ้างอิงถึงวัตถุเดียวกันนั้น เมื่อฟังก์ชัน ajax ส่งคืนในที่สุดจะอัปเดตคุณสมบัติ "เนื้อหา" ในออบเจ็กต์ดั้งเดิมที่ส่งคืน ลองมัน. :-)
Karen Zilles

1
Ps .successถูกเลิกใช้งานแล้ว ใช้.thenแทน docs.angularjs.org/api/ng/service/$http
redfox05

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

อย่าทำในคอนโทรลเลอร์เป็นอันขาด! เลว! คุณควรมีการเขียนเป็นบริการ แม้ว่าวิธีที่คุณเรียกว่าค่า json จะไม่ผิด แต่คุณควรมี Service ที่คืนสัญญาว่าจะไม่ทำสิ่งนี้ในคอนโทรลเลอร์ จากมุมมองการนำกลับมาใช้ใหม่เช่นกันสิ่งนี้น่ากลัว ตัวอย่างเช่นคุณกำลังดำเนินการและ $ http.get () ทุกครั้งที่คุณโหลดคอนโทรลเลอร์เทียบกับการโทรในเวอร์ชันแคชในบริการ
Downpour046

1

ฉันมีปัญหาประมาณนี้ ฉันต้องการแอปพลิเคชัน AngularJs ดีบักจาก Visual Studio 2013

โดยค่าเริ่มต้น 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>)

ต่อไปใช้ข้อมูลที่โหลดตามปกติ แน่นอนว่าเป็นเพียงวิธีแก้ปัญหาเท่านั้น


1

++สิ่งนี้ใช้ได้ผลสำหรับฉัน มันvanilla javascirptเหมาะสำหรับกรณีการใช้งานเช่น de-cluttering เมื่อทดสอบกับ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

อัปเดต

วิธีที่ง่ายกว่าที่ทำงานให้ฉันเป็นเพียงการรวมถึงที่ด้านล่างของรหัสกลับสิ่งที่functionJSON

// 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/MV5BMjEzNDUxMDI4OV5BMl5BanBnXkFtZTcwMjE2MzczNQ@@._V1_SX300.jpg",
         "Metascore": "N/A",
         "imdbRating": "8.2",
         "imdbVotes": "5",
         "imdbID": "tt1937109",
         "Type": "movie",
         "Response": "True"
   }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.