【问题标题】:prevent multiple upvote Angularjs防止多个赞成Angularjs
【发布时间】:2016-04-21 16:16:49
【问题描述】:

开始对我的英语感到抱歉。
我对这个问题进行了一些搜索,但对我没有任何帮助。

我的问题很简单:
我有一个投票系统,用户可以在其中投票(如 Stackoverflow)。但问题是用户可以多次投票(而且不是很好..)。
我尝试制作一个禁用 ng 的按钮,但如果我这样做,用户只能为所有帖子投票一次(我的意思是,如果他们投票支持“帖子 A”,他们就不能投票支持“帖子 B” )。

这是我的控制器功能:

$scope.incrementUpvotes = function(post) {
        posts.upvote(post);
    };

这是我的工厂函数:

o.upvote = function(post){
    return $http.put('/posts/' + post._id + '/upvote', null, {
        headers: {Authorization: 'Bearer '+auth.getToken()}
    }).success(function(data){
        post.upvotes += 1;
    });
};

这里是html:

<span class="glyphicon glyphicon-thumbs-up" ng-click="incrementUpvotes(post)"></span>

如果有人可以帮助我,那就太好了!提前致谢!

【问题讨论】:

  • 我确定您已经知道这一点,但只是提醒一下:无论您做什么,都无法阻止用户仅使用 Angular 多次投票。如果你想完全阻止它,你必须向服务器添加额外的检查。
  • 您必须在后端执行此操作,可能是一个映射表映射用户的问题问。当用户在问题详细信息中对帖子进行投票时,您会将用户和问题 ID 保存在映射表中,并且您将拥有一个 $scope 变量,该变量将其设置为真或假,并且在加载问题时再次使用映射表记录是否存在于映射表中并设置变量true或false
  • 我还没有角力,我认为通过这种方式是可能的,而且我浪费了很多时间..我应该以前问过。谢谢你的帮助,我明天试试。

标签: javascript angularjs


【解决方案1】:

请尝试使用button 或input 而不是span。因为disabled 在span 中不起作用。

<button id="{{ post._id + 'upvote' }}" class="glyphicon glyphicon-thumbs-up" ng-click="incrementUpvotes(post)"></button>

然后设置disabled你的upvote属性button在upvote之后为true。

o.upvote = function(post){
    return $http.put('/posts/' + post._id + '/upvote', null, {
        headers: {Authorization: 'Bearer '+auth.getToken()}
    }).success(function(data){
        post.upvotes += 1;
        angular.element(document.getElementById(post._id + 'upvote' ))[0].disabled = true;
    });
};

【讨论】:

  • ng-disabled 不适用于span,它只适用于输入元素..make it button 会起作用
  • 谢谢,我的答案已经改了,你能帮我检查一下是否正确
  • spans 上的禁用属性不会做任何事情。如果您使用ng-disabled 或.disabled = true,则没有任何区别。
  • 元素 ID 必须是唯一的。应该是&lt;input id="{{ post._id + 'upvoteInput' }}"之类的东西,然后在函数中,用同样的方法搜索:document.getElementById(post._id + 'upvoteInput')
  • 答案会一步一步来的。感谢您的建议。
【解决方案2】:

这更像是一个架构问题,而不是 javascript/angularjs 问题。有很多方法可以做到这一点。但想法是存储在数据库中并保存点赞信息,否则用户只需刷新页面并再次点赞即可。

最直接的解决方案是:您必须在用户级别将投票信息存储在后端。当您查询用户信息时,存储一个投票的帖子列表,如下所示:

myDataService 应如下所示:

angular.module("app", []).service("myDataService", ["$http","$q","$rootScope", function myDataService($http, $q, $rootScope) {
    var myDataService = this;

    myDataService.getPostsUpvoted = function(userId) {
        var defer = $q.defer();

        //here you format your payload to deliver userId to the api backend
        var payload = { userId: userId };

        //your api backend 'getpostsupvoted' should accept a userId, then in return it should
        //deliver a list of posts upvoted by that user
        $http.post("/api/getpostsupvoted", payload).then(function (data, status, headers, config) {
            //call success
            defer.resolve(data);
        }, function(data, status, headers, config) {
            //an error occurred
            defer.reject(data);
        });

        return defer.promise;
    }

    return myDataService;
})];

然后,这就是您在控制器中使用服务的方式。

//inject scope and myDataservice into controller
angular.module("app", []).controller("MainCtrl", ["$scope", "myDataService", function($scope, myDataService) {

    //create a new array to hold a list of upvotes
    $scope.user.upVoted = [];
    myDataService.getPostsUpvoted($scope.user.id).then(function(data) {
        //set upvoted array to data
        $scope.user.upVoted = data;
    }, function(error) {
        //blah an error occurred
    });

})];

在您的控制器中,提供一个函数来检查帖子是否已被点赞。

$scope.IsUpvotedAlready = function(postId) {

    if($scope.user.upVoted.indexOf(postId) > -1)
        return true;

    return false;

}

您还必须将 post._id 推送到 upVoted 数组并保留在那里。

$scope.incrementUpvotes = function(post) {

    //check if it's already been upvoted, then do nothing
    if($scope.user.upVotes.indexOf(post._id) > -1)
        return;

    posts.upvote(post);

    $scope.user.upVoted.push(post._id);
};

然后,在显示帖子的 ng-repeat 指令中,检查点赞列表是否包含 post._id。

<div ng-repeat="post in posts">
    <div ng-if="IsUpvotedAlready(post._id)">
        <!-- display something since already upvoted !-->
    </div>
    {{ post }}
</div>

【讨论】:

  • 感谢您的回答!我现在不能尝试,但它似乎很好!我明天去考试。
  • 只有一件事我不确定,我是否必须将您的第一个块代码插入我的工厂?
【解决方案3】:

在迭代帖子时,在模板中为每个帖子设置一个标志,用于标识它是否已被点赞。

在upvote 函数中将该标志标记为真,并在ng-disabled 指令中使用它,如下所示:

ng-disabled={{post.isUpvoted}}

【讨论】:

  • 感谢回答,我明天试试
猜你喜欢
  • 1970-01-01
  • 2021-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-19
  • 1970-01-01
  • 2014-05-25
相关资源
最近更新 更多