0

我正在使用 Angular Meteor,但我的对象/数组有问题。我有这个代码:

angular.module("learn").controller("CurriculumDetailController", ['$scope', '$stateParams', '$meteor',
  function($scope, $stateParams, $meteor){
    $scope.curriculum = $meteor.object(CurriculumList, $stateParams.curriculumId);

    $scope.resources = _.map($scope.curriculum.resources, function(obj) {
      return ResourceList.findOne({_id:obj._id})
    });

    console.log($scope.resources)
  }]);

我正在尝试迭代“资源”,这是课程对象中的一个嵌套数组,查找“资源列表”集合中的每个值,并在范围内返回新数组。

问题是,有时有效,有时无效。当我加载页面并通过 UI 路由器链接访问它时。我得到了预期的数组。但是如果页面被刷新,$scope.resources 是一个空数组。

我的想法是异步调用发生了一些事情,但无法找到解决方案。我仍然安装了自动发布包。任何帮助,将不胜感激。

4

1 回答 1

0

What you're going to do is return a cursor containing all the information you want, then you can work with $meteor.object on the client side if you like. Normally, publishComposite would look something like this: (I don't know what your curriculum.resources looks like)

Use this method if the curriculum.resources has only ONE id:

// this takes the place of the publish method
Meteor.publishComposite('curriculum', function(id) {
  return {
      find: function() {

        // Here you are getting the CurriculumList based on the id, or whatever you want
        return CurriculumList.find({_id: id});
      },
      children: [
        {
          find: function(curr) {
            // (curr) will be each of the CurriculumList's found from the parent query
            // Normally you would do something like this:
            return ResourceList.find(_id: curr.resources[0]._id);
          }
        }
      ]
    }
})

This method if you have multiple resources:

However, since it looks like your curriculum is going to have a resources list with one or many objects with id's then we need to build the query before returning anything. Try something like:

// well use a function so we can send in an _id
Meteor.publishComposite('curriculum', function(id){
    // we'll build our query before returning it.
    var query = {
        find: function() {
            return CurriculumList.find({_id: id});
        }
    };        

    // now we'll fetch the curriculum so we can access the resources list
    var curr = CurriculumList.find({_id: id}).fetch();

    // this will pluck the ids from the resources and place them into an array
    var rList = _.pluck(curr.resources, '_id');

    // here we'll iterate over the resource ids and place a "find" object into the query.children array.

    query.children = [];

    _.each(rList, function(id) {
        var childObj = {
            find: function() {
                return ResourceList.find({_id: id});
            }
        };
        query.children.push(childObj)
    })

    return query;
});

So what should happen here (I didn't test) is with one publish function you will be getting the Curriculum you want, plus all of it's resourceslist children.

Now you will have access to these on the client side.

$scope.curriculum = $meteor.object(CurriculumList, $stateParams.curriculumId);
// collection if more than one, object if only one.
$scope.resources = $meteor.collection(ResoursesList, false);

This was thrown together somewhat quickly so I apologize if it doesn't work straight off, any trouble I'll help you fix.

于 2015-10-23T16:30:33.770 回答