选择列表时立即默认 api 调用完成 - MEAN.JS

Immediate default api call done when selecting list - MEAN.JS

我没有提供基本的 CRUD 模块 articles,而是有一个类似的模块 friendsfriend 只是另一个 user,但与 user 模块分开。我试图做到这一点,当用户选择查看好友列表时,他们会看到 他们自己的 好友列表,而不是 friends 中存储的所有好友collection 在 mongo 中。 mongo中的一个friend的结构是collection:

{
    "_id" : ObjectId("587b9e16d1bdf314181b354e"),
    "user" : ObjectId("5867c5e92fa4e91008788f80"),
    "added" : ISODate("2017-01-15T16:06:46.975Z"),
    "friend" : {
        "firstName" : "b",
        "lastName" : "b",
        "email" : "b@b.com",
        "profileImageURL" : "modules/users/client/img/profile/default.png",
        "roles" : [
               "user"
        ],
        "created" : "2017-01-11T17:28:19.849Z",
        "__v" : 0,
        "username" : "bbbbbb",
        "provider" : "local",
        "displayName" : "b b",
        "_id" : "58766b337f091f842addfd5a"
    },
    "__v" : 0
}

所以 user 字段是这个 friend 分配给的用户, friend object 是实际的朋友。

我只需添加另一条将用户作为参数的路由,就可以很轻松地完成 api 调用:

/api/:userId/friends/:friendId

/api/:userId/friends

我意识到 (这是 MEAN.JS 中的默认设置),在客户端中,如果用户选择查看好友列表, 立即调用 ALL (/api/friends) collection 中的朋友 mongo .

我查看了整个客户端,但看不到这个调用是从哪里发出的!

我想做的是找到这个调用的位置并更改它,以便它包含 :userId 作为参数,这样只会让用户成为朋友。

在我看来,一旦您点击模板查看朋友,控制器 应该FriendsService 进行 ngResource 查询获取特定用户的好友:

function FriendsService($resource) {
    return $resource('api/:userId/friends/:friendId', {
        userId: '@user',
        friendId: '@_id'
    }, {
        update: {
            method: 'PUT'
        }
    });
}

...但显然不是这样的

编辑:

我很高兴 $stateProvider 在好友模块客户端的配置中设置:

$stateProvider
    .state('friends', {
        abstract: true,
        url: '/friends',
        template: '<ui-view/>'
    })
    .state('friends.list', {
        url: '',
        templateUrl: 'modules/friends/client/views/list-friends.client.view.html',
        controller: 'FriendsListController',
        controllerAs: 'vm',
        data: {
            pageTitle: 'Friends List'
        }
    });

所以当我点击 url /friends 时,应该会发生什么,因为没有与之关联的控制器或模板?

然而,在friends.client.config.js中,菜单服务是:

// Add the dropdown list item
menuService.addSubMenuItem('topbar', 'friends', {
    title: 'List Friends',
    state: 'friends.list'
});

所以我的理解是,当单击 UI 中列出朋友的 sub-menu 选项时,它使用映射到 FriendsListContoller.

的状态
function FriendsListController(FriendsService) {
    var vm = this;

    vm.friends = FriendsService.query();
}

所以会查询ngResourceFriendsServiceFriendsService:

function FriendsService($resource) {
    return $resource('api/:userId/friends/:friendId', {
        userId: '@user',
        friendId: '@_id'
    }, {
        update: {
            method: 'PUT'
        }
    });
}

所以在我看来,当用户选择查看好友列表时,应该调用 /api/:userId/friends/:friendId

关键是我可以在控制台中看到,选择查看朋友列表时,正在呼叫/api/friends,而是得到 all 朋友在 collection 在 mongo 中,无论分配给谁:

呼叫显然是从某个地方的客户端发出的,但找不到位置。

3 个问题:

  1. 我的逻辑对吗?在某种意义上,当用户选择查看好友列表时,服务被查询?
  2. 在服务中,参数userIdfriendId设置为@user(我设置的)@_id (已经存在)。我的假设是这些是 mongo 中 collection 中的字段,对吗?无论如何我可以调试传递给这个调用的值吗?
  3. 在哪里调用“/api/friends”?因为,在我的脑海中逻辑上,我找不到它在客户端中被调用的地方 (可能是因为我对 MEAN.JS 结构还不够了解)

您应该主要在服务器端进行验证。

但首先要做的是:考虑到您的朋友 api 在结构上与文章示例 api 相似,一旦发出请求,您应该检查定义了哪些路由端点服务器side,主要在/modules/friends/server/routes中的routes.js文件中,同时比较哪些controller会处理server端的逻辑,应该在/modules/friends/server/controllers.

现在,如果您仔细查看,路由文件中有一行:

// Finish by binding the article middleware
app.param('articleId', articles.articleByID);

这是解决您问题的起点,您应该像这样绑定 userIdfriendId

app.param('userId', friends.userByID);
app.param('friendId', friends.friendByID);

以便在服务器控制器中您可以通过 req.userIdreq.friendId 直接访问两者。

这应该是要走的路,然后在 GET /api/:userId/friends 的控制器中,您必须添加所需的逻辑,以便 mongoose 仅​​查询该特定用户的朋友和 return他们。

但是,如果您的朋友 API 不在单独的模块中,而只是对已定义的用户模块的补充,那么您可以对用户模块进行类似的调整。

修复比较简单,之前没有想到这一点我觉得很愚蠢。
MEAN.JS 有一个 Authentication 工厂可以 return 会话中的当前用户 (Authentication.user)
只需在 REST 调用中使用 Authentication.user._id 作为 userId 的参数,我就能够做到这一点。这是我的新 FriendsService:

function FriendsService($resource, Authentication) {
    return $resource('api/:userId/friends/:friendId', {
        userId: Authentication.user._id,
        friendId: '@_id'
    }, {
        update: {
            method: 'PUT'
        }
    });
}

您似乎没有将 userId 传递给 FriendsService,这就是您执行 vm.friends = FriendsService.query(); 查询时触发 /api/friends url 的原因。您需要更改 FriendsService 以获取 userId 作为输入

你可以这样写你的工厂

app.factory('FriendsService', function ($resource) {
return $resource('/:entity/:id/:action/:friendId', {id: '@id',friendId: '@friendId'}, {
    firendsList: {method: 'PUT', params: {entity: 'api',action:'friends'}}, // this calls the api/userId/friends api in PUT method you can use friendId here too for understanding i seperated the service. 
    fetchFriend:{method:'GET',params:{entity:'api',action:'friends'}}  // this calls the api/userId/friends/friendId in GET method
});

注意: 您可以将 entityaction 分别设置为静态 api、`朋友。或者可以保持其可配置性并将其用于其他方法。

现在您可以在控制器中编写

function FriendsListController(FriendsService) {

FriendsService.firendsList({'id': 'userId'}, function (response) {
            alert('Edited successfully');
            console.log(response)
        }, function (error) {
            if (error)
                alert(error)
        })

FriendsService.fetchFriend({'id': 'userId',friendId:'friendId'}, function (response) {
            alert('Friend Fetched successfully');
            console.log(response)
        }, function (error) {
            if (error)
                alert(error)
        })
}
  1. 我的逻辑正确吗?在某种意义上,当用户选择查看好友列表时,会查询该服务?

回答:当用户选择查看好友列表时,应该调用friendsList服务。

  1. 在服务中,参数 userId 和 friendId 设置为@user(我设置)或@_id(已经存在)。我的推测是这些是 mongo 中集合中的字段,对吗?无论如何我可以调试传递给这个调用的值吗?

回答: userIdfriendId并不是真正的mongodb集合中的字段,这些是使用的资源变量要调用服务 API,在调用服务时应传递 userIdfriendId。如果未传递这些参数,资源会将其视为空白并调用 /api/friends API,因为未定义 userIdfriendId

  1. 呼叫 /api/friends 是在哪里进行的?因为,从逻辑上讲,我找不到在客户端调用它的位置(可能是因为我对 MEAN.JS 结构还不够了解)

答案:答案在第二个问题本身,如果您不传递 userId 的值,angular 服务将省略 userId API url 中的键,它基本上重组为 /api/friends

希望对您有所帮助。