MeteorJS是建立和发展的好方法。访问我的文件

时间:2014-08-05 15:22:38

标签: javascript mongodb meteor

我正在尝试构建一个MeteorJS应用程序。这是一种播放列表管理器。

看起来像spotify,有3个colums所以我制作了3个模板, 从左到右 : - 播放列表列表 - 所选播放列表的媒体 - 所选媒体的详细信息

所以这是我的代码:

server.js

Playlists = new Meteor.Collection("playlists");

if (Meteor.isServer) {
  Meteor.startup(function() {
    if (Playlists.find().count() === 0) {
      var names = ["test1",
                   "222",
                   "test3",
                   "444",
                   "test5",
                   "666"];
      for (var i = 0; i < names.length; i++)
        Playlists.insert({'name': names[i]});
    }

    return (
      Meteor.methods({
        addPlaylist: function(playlistName) {
          Playlists.insert({'name': playlistName, 'medias': []});
        },
        delPlaylist: function(playlistId) {
          Playlists.remove({'_id': playlistId});
        },
        renPlaylist: function(playlistId, newName) {
          Playlists.update({'_id': playlistId}, {'$set': {'name': newName}});
        },
        addMedia: function(playlistId, newMedia) {
          var current_playlist = Playlists.findOne({'_id': playlistId});
          Playlists.update(current_playlist, {$push: {'medias': newMedia}});
        }
      })
    );
  });

  Playlists.allow({
    insert: function(userId, doc) {
      return (false);
    },
    update: function(userId, doc, fields, modifier) {
      return (false);
    },
    remove: function(userId, doc) {
      return (false);
    }
  });

}

我的模板:

<template name="t_playlistsCol">
  <button id="newPlaylist" class="btn btn-primary" type="button">
    New Playlist
  </button>
  <div id="listPlaylist">
    {{#each playlists}}
      <button class="playlist {{Pselected}} btn btn-default" type="button">
        {{name}}
      </button>
    {{/each}}
  </div>
</template>

<template name="t_mediasCol">
  {{#if current_playlist}}
    <div class="menuPlaylist">
      <img id="playPlaylist" class="btn" src="icon_play1.png">
      <h4>{{current_playlist}}</h4>
      <div id="optionsPlaylist">
        <button id="insertMedia" class="btn btn-primary">Insert</button>
        <button id="renamePlaylist" class="btn btn-info">Rename</button>
        <button id="deletePlaylist" class="btn btn-danger">Delete</button>
      </div>
    </div>
    <table id="listMedias">
      <thead>
        <tr>
          <th class="mediaName">Titre</th>
          <th class="mediaType">Type</th>
          <th class="mediaTime">Durée</th>
        </tr>
      </thead>
      <tbody>
        {{#each medias}}
          <tr class="media {{Mselected}}">
            <td class="mediaName">{{name}}</td>
            <td class="mediaType">{{type}}</td>
            <td class="mediaTime">{{time}}</td>
          </tr>
        {{/each}}
      </tbody>
    </table>
  {{else}}
    <div class="menuPlaylist">
      <h3 id="noPlaylist">Select a playlist</h3>
    </div>
  {{/if}}
</template>

<template name="t_previewCol">
  {{#if current_media}}
    <div class="menuPreview">
      <p>{{current_media}}</p>
    </div>
  {{else}}
    <div class="menuPreview">
      <h3 id="noPreview">Select a media</h3>
    </div>
  {{/if}}
</template>

client.js:

(
Playlists = new Meteor.Collection("playlists");

if (Meteor.isClient) {
  Template.t_playlistsCol.playlists = function() {
    return (Playlists.find({}, {sort: {"name": 1}}));
  };

  Template.t_playlistsCol.events = {
    'click #newPlaylist': function() {
      var playlistName = prompt("Nom de la playlist : ");
      if (playlistName) {
        Meteor.call('addPlaylist', playlistName);
      }
    },
    'click .playlist': function() {
      Session.set("selected_playlist", this._id);
    }
  };

  Template.t_playlistsCol.Pselected = function() {
    return ( Session.equals("selected_playlist", this._id) ? "Pselected" : '' );
  };

  Template.t_mediasCol.current_playlist = function() {
    var playlist = Playlists.findOne(Session.get("selected_playlist"));
    return (playlist && playlist.name);
  };

  Template.t_mediasCol.medias = function() {
    var current_playlist = Playlists.findOne(Session.get("selected_playlist"));
    return ( current_playlist.medias );
  };

  Template.t_mediasCol.events = {
    'click #insertMedia': function() {
      var playlistId = Session.get("selected_playlist");
      var newMedia = {
        name: "mediaTest",
        type: "img",
        time: "00:15"
      };
      newMedia._id = new Meteor.Collection.ObjectID();
      Meteor.call('addMedia', playlistId, newMedia);
    },
    'click #deletePlaylist': function() {
      var playlistId = Session.get("selected_playlist");
      Meteor.call('delPlaylist', playlistId);
    },
    'click #renamePlaylist': function() {
      var playlist = Playlists.findOne(Session.get("selected_playlist"));
      var newName = prompt("Renommer " + playlist.name + " en :");
      if (newName) {
        Meteor.call('renPlaylist', playlist._id, newName);
      }
    },
    'click .media': function() {
      Session.set("selected_media", this._id);
    }
  };

  Template.t_mediasCol.Mselected = function() {
    return ( Session.equals("selected_media", this._id) ? "Mselected" : "" );
  };

  Template.t_previewCol.current_media = function() {
    var playlistId = Session.get("selected_playlist");
    var mediaId = Session.get("selected_media");
    var playlist = Playlists.find({'_id': playlistId});
    return(playlist.medias[0] && playlist.medias[0].name);
  };

  Accounts.ui.config({
    passwordSignupFields: 'USERNAME_ONLY'
  });
}

我是新手,我正在学习流星3周。

SO,我的问题就是这样,我希望用户能够选择媒体并使用模板“t_previewCol”查看其详细信息。 它适用于播放列表,但我没有帮助器“Template.t_previewCol.current_media”我想要的,它在我执行console.log调试时打印此错误:

Exception in template helper:
Template.t_previewCol.current_media@http://localhost:3000/client
/client.js?7212665c7dc29cf721272fa4cabeb499f2e18bf5:69:5
bindToCurrentDataIfIsFunction/<@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2448:7
Blaze.wrapCatchingExceptions/<@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1552:7
Spacebars.call@http://localhost:3000/packages
/spacebars.js?8717c3bee1160f47e7a46ea4e1bd0796f944cad8:169:5
@http://localhost:3000/client
/template.client.js?d2b9a924f64621cd0bcfc1292538f5b63523959a:117:5
Blaze.If/</<@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2275:11
viewAutorun/<@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1805:7
Blaze.withCurrentView@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2038:5
viewAutorun@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1804:5
Deps.Computation.prototype._compute@http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:214:5
Deps.Computation@http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:148:5
Deps.autorun@http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:362:7
Blaze.View.prototype.autorun@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1803:7
Blaze.If/<@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2277:1
fireCallbacks@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1818:9
Deps.nonreactive@http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
Blaze._fireCallbacks/<@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1815:5
Blaze.withCurrentView@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2038:5
Blaze._fireCallbacks@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1814:3
Blaze.materializeView@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1830:3
.visitObject@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1458:7
.visit@http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:116:7
doMaterialize@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1862:13
Deps.nonreactive@http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
doRender@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1860:7
viewAutorun/<@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1805:7
Blaze.withCurrentView@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2038:5
viewAutorun@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1804:5
Deps.Computation.prototype._compute@http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:214:5
Deps.Computation@http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:148:5
Deps.autorun@http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:362:7
Blaze.View.prototype.autorun@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1803:7
Blaze.materializeView/<@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1851:5
Deps.nonreactive@http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
Blaze.materializeView@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1850:3
.visitObject@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1458:7
.visit@http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:116:7
.visitArray@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1363:7
.visit@http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:114:9
.visitTag@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1441:9
.visit@http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:101:11
.visitArray@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1363:7
.visit@http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:114:9
.visitTag@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1441:9
.visit@http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:101:11
.visitArray@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1363:7
.visit@http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:114:9
doMaterialize@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1862:13
Deps.nonreactive@http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
doRender@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1860:7
viewAutorun/<@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1805:7
Blaze.withCurrentView@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2038:5
viewAutorun@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1804:5
Deps.Computation.prototype._compute@http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:214:5
Deps.Computation@http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:148:5
Deps.autorun@http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:362:7
Blaze.View.prototype.autorun@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1803:7
Blaze.materializeView/<@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1851:5
Deps.nonreactive@http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
Blaze.materializeView@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1850:3
.visitObject@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1458:7
.visit@http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:116:7
.visitArray@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1363:7
.visit@http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:114:9
doMaterialize@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1862:13
Deps.nonreactive@http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
doRender@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1860:7
viewAutorun/<@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1805:7
Blaze.withCurrentView@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2038:5
viewAutorun@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1804:5
Deps.Computation.prototype._compute@http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:214:5
Deps.Computation@http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:148:5
Deps.autorun@http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:362:7
Blaze.View.prototype.autorun@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1803:7
Blaze.materializeView/<@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1851:5
Deps.nonreactive@http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
Blaze.materializeView@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1850:3
Blaze.render@http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2068:3
instantiateBody@http://localhost:3000/packages
/templating.js?e2c0d3bbe4292a0b20c3083eaf4fcd0f5f91bb52:245:7
ready@http://localhost:3000/packages
/meteor.js?7a66be7a03504cd2c18dd47b699e6233b60675ed:641:6

也许是因为我建立文件的方式,它们看起来像那样:

{
  _id: "idP",
  name: "nameP",
  medias: [
    {
      _id: "idM1",
      name: "nameM1"
    },
    {
      _id: "idM2",
      name: "nameM2"
    },
    ...
  ]
}

我试图向你提供有关我问题的最多细节,希望有人能帮助我。

感谢。

编辑: 当用户点击媒体时,我已经修复了“预览列”的行为

Template.t_previewCol.current_media = function() {
var playlistId = Session.get("selected_playlist");
var mediaId = Session.get("selected_media");
var playlist = Playlists.findOne({'_id': playlistId});
for (var i = 0 ; i < playlist.medias.length ; ++i)
  if (playlist.medias[i]._id._str === mediaId._str)
    return(playlist.medias[i] && playlist.medias[i].name);
return (null);
};

我正在尝试

if (playlist.medias[i]._id === mediaId)

但是因为我使用Meteor.Collection.ObjectId()分配了medias._id,所以它无效。

现在我只想了解上面粘贴的错误。

1 个答案:

答案 0 :(得分:0)

Playlists.find返回一个游标。我想你想要Playlists.findOne

  Template.t_previewCol.current_media = function() {
    var playlistId = Session.get("selected_playlist");
    var mediaId = Session.get("selected_media");
    var playlist = Playlists.findOne({'_id': playlistId});
    return(playlist.medias[0] && playlist.medias[0].name);
  };