2017-03-09 187 views
0

我正在建立一個網站上的音樂曲目數據庫。該數據庫如下:角度鏈承諾數組

  • 音樂表包含MusicID提供和標題
  • musicrights表包含MusicID提供MEMBERID
  • 成員表包含MEMBERID和的MemberInfo 。

我試圖建立對象的數組在我database服務,其中每個條目代表包含其權利人的軌道(包含aubout一個權利人而不是他的名字信息)及其成員信息(包括名稱等) 。後端是sailsjs,代碼如下:

angular.module("myapp").service("database", ["$q", "$http", function($q, $http) { 
 

 
    var database = {}; 
 

 
    function getHolderMember(rightHolder) { 
 
    return ($http.get("/api/members?where=" + JSON.stringify({ 
 
     memberid: rightHolder.memberid 
 
    })).then(function (res) { 
 
     rightHolder.member = res.data[0]; 
 
     return (rightHolder); 
 
    })); 
 
    } 
 

 
    function getRightHolders(doc) { 
 
    return ($http.get("/api/musicrights?where=" + JSON.stringify({ 
 
     musicid: doc.musicid 
 
    })).then(function(res) { 
 
     // array of promises : 
 
     // each rightholder of a document has to solve member info 
 
     var rightHolders = []; 
 
     for (var i in res.data) { 
 
     var rightHolder = { 
 
      member: res.data[i].memberid, 
 
      type: res.data[i].membertype, 
 
      rights: res.data[i].memberrights 
 
     }; 
 
     rightHolders.push(getHolderMember(rightHolder)); 
 
     } 
 
     return ($q.all(rightHolders)); 
 
    }).then(function(rightHolders) { 
 
     // expected array of one or two rightholders, 
 
     // enriched with member information 
 

 
     // actually returns array of one or two arrays of 30 members 
 
     // without rightholder info 
 
     console.log(rightHolders); 
 
     doc.rightHolders = rightHolders; 
 
     return (doc); 
 
    })); 
 
    } 
 

 
    database.music = function(q) { 
 
    return ($http.get("/api/music?where=" + JSON.stringify({ 
 
     or: [{ 
 
     title: { 
 
      contains: q 
 
     } 
 
     }, { 
 
     subtitle: { 
 
      contains: q 
 
     } 
 
     }] 
 
    })).then(function(res) { 
 
     // array of 30 promises : 
 
     // each one of 30 documents has to resolve its rightholders 
 
     var documents = []; 
 
     for (var i in res.data) { 
 
     documents.push(getRightHolders(res.data[i])); 
 
     } 
 
     return ($q.all(documents)); 
 
    })); 
 
    } 
 

 
    return (database); 
 
}]);

承諾的第一陣列似乎按預期方式工作,但不是第二個在getRightHolders。奇怪的是,這個函數返回一個或兩個promise的數組,這是rightHolders等待它們的成員信息。但在console.log響應的回調中,我得到一個或兩個數組(按推送的promise的數量),但此數組的元素是30個memberinfo而不是一個memberinfo的數組。我不明白這個$ q.all()調用是如何與前一級$ q.all混合的。

的數據結構大致是這樣

  • 文件[]($ HTTP => 30級響應)
    • music.musicid
    • music.rightHolders []($ HTTP = > 1,2,3個響應)
      • rightholder.rights
      • rightholder.member($ HTTP => 1反應)
        • member.memberinfo

理解任何幫助。謝謝 !

更新:謝謝你的回答,它像一個魅力。下面是更新後的代碼,以及遷移服務,它將數據格式不同(有一些數據庫遷移正在進行)。我把它放在第一個例子中,但是你的回答給了我這種整齊的語法。

angular.module("myApp").service("database", ["$q", "$http", "migrate", function($q, $http, migrate) { 
 

 
     var database = {}; 
 

 
     function getHolderMember(rightHolder) { 
 
      return ($http.get("/api/members?where=" + JSON.stringify({ 
 
      memberID: rightHolder.member 
 
      })).then(function(res) { 
 
      return (migrate.member(res.data[0])); 
 
      }).then(function(member) { 
 
      rightHolder.member = member; 
 
      return (rightHolder); 
 
      })); 
 
     } 
 

 
     function getRightHolders(doc) { 
 
      return ($http.get("/api/rightHolders?where=" + JSON.stringify({ 
 
      musicID: doc.musicID 
 
      })).then(function(res) { 
 
      return (
 
       $q.all(res.data 
 
       .map(migrate.rightHolder) 
 
       .map(getHolderMember) 
 
      ) 
 
      ); 
 
      }).then(function(rightHolders) { 
 
      doc.rightHolders = rightHolders; 
 
      return (doc); 
 
      })); 
 
     } 
 

 
     database.music = function(q) { 
 
      return ($http.get("/api/music?where=" + JSON.stringify({ 
 
      or: [{ 
 
       title: { 
 
        contains: q 
 
       } 
 
       }, 
 
       { 
 
       subtitle: { 
 
        contains: q 
 
       } 
 
       } 
 
      ] 
 
      })).then(function(res) { 
 
      return (
 
       $q.all(res.data 
 
       .map(migrate.music) 
 
       .map(getRightHolders) 
 
      ) 
 
      ); 
 
      })); 
 
     } 
 

 
     return (database); 
 
     }

+0

什麼是'無功rightHolder'在'getRightsHolders'功能的目的是什麼?它看起來像你創建它來傳遞給'getHolderMember',但是'getHolderMember'只使用它的三個屬性之一。 – JLRishe

+0

是的,我曾在'getHolderMember'的'$ http'調用之後有'then',它將返回的成員存儲在請求的RightHolder中。這三個屬性將在視圖中使用,如'documents [n] .rightHolders [n] .rights'或'documents [n] .rightHolders [n] .member.memberInfo'。爲了使這項工作做了很多修改,我想我應該把它放在示例中以便清楚。 –

回答

1

我不太清楚你是如何得到你所描述的結果,而是你的邏輯更令人費解比它需要的是,我認爲這可能是導致問題你看到了。您給getRightsHolders函數負責返回文檔,並基於上面的註釋,它聽起來像以前有getHolderMember()函數做類似的事情,然後停止這樣做。

我們可以通過讓每個函數負責它正在處理的實體並使用.map()而不是for(請不要在數組中使用for..in)來清除它。

請這給一試:

angular 
    .module("myapp") 
    .service("database", ["$q", "$http", function($q, $http) { 
    var database = {}; 

    function getHolderMember(memberId) { 
     var query = JSON.stringify({ memberid: memberid }); 
     return $http.get("/api/members?where=" + query) 
      .then(function (res) { 
       return res.data[0]; 
      }); 
    } 

    function populateRightsHolderWithMember(rightsHolder) { 
     return getHolderMember(rightsHolder.memberid) 
     .then(function (member) { 
      rightsHolder.member = member; 
      return rightsHolder; 
     }); 
    } 

    function getRightHolders(doc) { 
     var query = JSON.stringify({ musicid: doc.musicid }); 

     return $http.get("/api/musicrights?where=" + query) 
     .then(function(res) { 
      return $q.all(res.data.map(populateRightsHolderWithMember)); 
     }); 
    } 

    function populateDocumentWithRightsHolders(document) { 
     return getRightsHolders(document) 
     .then(function(rightsHolders) { 
      document.rightsHolders = rightsHolders; 
      return document; 
     }); 
    } 

    database.music = function(q) { 
     return $http.get("/api/music?where=" + JSON.stringify({ 
     or: [{ 
      title: { 
      contains: q 
      } 
     }, { 
      subtitle: { 
      contains: q 
      } 
     }] 
     })).then(function(res) { 
     return $q.all(res.data.map(populateDocumentWithRightsHolders)); 
     }); 
    } 

    return (database); 
    }]); 
+0

爲什麼'for .. in'不能與數組一起使用? –

+1

@ Pierre-AlexisCiavaldini http://stackoverflow.com/questions/500504/why-is-using-for-in-with-array-iteration-a-bad-idea – JLRishe