【问题标题】:How to add id of an object in another object with AngularJS如何使用AngularJS在另一个对象中添加一个对象的id
【发布时间】:2016-03-24 23:04:02
【问题描述】:

我有两个对象,事件和评论:

   {
    "name": "events",
    "fields": {
      "name": {
        "type": "string"
      },
      "date": {
        "type": "datetime"
      },
      "time": {
        "type": "datetime"
      },
      "info": {
        "type": "text"
      },
      "users": {
        "collection": "users_events",
        "via": "event"
      },
      "eventCommentsId": {
        "collection": "comments",
        "via": "eventId"
      },
    }
  },
  {
    "name": "comments",
    "fields": {
      "content": {
        "type": "text"
      },
      "owner": {
        "object": "users"
      },
      "eventId": {
        "object": "events"
      },
      "date": {
        "type": "datetime"
      }
    }
  }

每个事件都应该有自己独特的 cmets 集合。所以,它是一对多的关系。

现在,我可以获取所有的 cmets,而不仅仅是对应每个事件的那些。我的想法是我需要在每个评论中包含事件的 ID。但是,我不完全确定该怎么做。

如果有人能帮我解决这个问题,那就太棒了!

我正在使用 Ionic/AngularJS 构建应用程序,并且正在使用 Backand 存储我的数据。

提前致谢!

.controller('EventDetailCtrl', ['$scope', '$stateParams', '$ionicSideMenuDelegate', 'EventService', 'CommentService',function($scope, $stateParams, $ionicSideMenuDelegate, EventService, CommentService) { 
  $scope.openMenu = function () {
    $ionicSideMenuDelegate.toggleLeft();
  };    

  var id = $stateParams.id;
  EventService.getEvent(id).then(function(response){
   $scope.event = response.data;
});

  $scope.comments = [];
  $scope.input = {};

  function getAllComments() {
    CommentService.getComments()
    .then(function (result) {
      $scope.comments = result.data.data;
    });
  }

  $scope.addComment = function() {
    CommentService.addComment($scope.input)
    .then(function(result) {
      $scope.input = {};
      getAllComments();
    });
  }

  $scope.deleteComment = function(id) {
    CommentService.deleteComment(id)
    .then(function (result) {
      getAllComments();
    });
  }

  getAllComments();

}])

.service('CommentService', function ($http, Backand) {    
  var baseUrl = '/1/objects/';
  var objectName = 'comments/';

  function getUrl() {
    return Backand.getApiUrl() + baseUrl + objectName;
  }

  function getUrlForId(id) {
    return getUrl() + id;
  }

  getComments = function () {
    return $http.get(getUrl());
  };

  addComment = function(event) {
    return $http.post(getUrl(), event);
  }

  deleteComment = function (id) {
    return $http.delete(getUrlForId(id));
  };

  getComment = function (id) {
    return $http.get(getUrlForId(id));
  };


  return {
    getComments: getComments,
    addComment: addComment,
    deleteComment: deleteComment,
    getComment: getComment
  }   
})

【问题讨论】:

  • 你最好从后端而不是在 JS (angularjs) 中做!

标签: angularjs json ionic-framework backand


【解决方案1】:

最好将从后端获取特定事件的所有 cmets 的逻辑移动,而不是从服务器获取所有内容并在前端进行过滤。 您可以拨打电话,例如:

http://mysite/getComments?eventId=2533213

在您的 cmets 架构(用于 DB)中,您可以将一个字段设置为 eventId。然后,您可以从 DB 获取调用中提供的具有事件 ID 的所有 cmets,并返回到您的应用作为响应。

在前端你可以这样做:

控制器:

function getCommentsById(event) {
    CommentService.getCommentsById(event)
    .then(function (result) {
      $scope.comments = result.data.data;
    });
  }

服务:

getCommentsById = function (event) {
    return $http.get(getUrl() + "?eventId=" + event.id); //supposing you have event.id
  };

【讨论】:

    【解决方案2】:

    您还可以在 Backand 的仪表板中创建一个查询并将其命名为 GetCommentsByEventId 并使用 api 端点 Backand.getApiUrl() + '/1/query/data/GetCommentsByEventId' 您可以传递 id 并获得该事件的 cmets。 (见下面的截图)

    在使用 SQL SELECT * FROM comments WHERE event='{{eventId}}' 的查询中,您将获得该事件 ID 的 cmets。

    或者您可以在 API url 中使用过滤器,例如 Backand.getApiUrl() + /1/comments?filter={"fieldName":"event","operator":"in", "value": "33"}(为了便于阅读,此处未编码 url,33 是 eventId)

    我用于演示的 DB 模型如下图所示:

    DB模型json如下:

        [
    {
        "name": "users",
        "fields": {
            "email": {
                "type": "string"
            },
            "firstName": {
                "type": "string"
            },
            "lastName": {
                "type": "string"
            },
            "user": {
                "collection": "comments",
                "via": "user"
            }
        }
    },
    {
        "name": "events",
        "fields": {
            "title": {
                "type": "string"
            },
            "created_at": {
                "type": "datetime"
            },
            "eventId": {
                "collection": "comments",
                "via": "event"
            }
        }
    },
    {
        "name": "comments",
        "fields": {
            "event": {
                "object": "events"
            },
            "user": {
                "object": "users"
            },
            "text": {
                "type": "string"
            }
        }
    }
    ]
    

    在 DB 模型中,我只会将 events 模型中的 eventId 重命名为 eventCommentsId 明确表示它是对 cme​​ts 的引用。

    请在下面找到演示代码(此处不工作,Backand 脚本中的操作不安全)或此jsfiddle 中的工作演示。

    可以对 Angular 代码进行一些重构,但它可以正常工作。如果还有其他不正确的地方,请告诉我,因为这是我使用 Backand 的第一个示例。

    此外,演示中没有用户登录,这就是为什么所有内容都将添加 userId = 1。

    angular.module('demoApp', ['ionic', 'backand'])
      //Update Angular configuration section
      .config(function(BackandProvider) {
        BackandProvider.setAppName('myfirstapp123');
        //BackandProvider.setSignUpToken('-token-');
        BackandProvider.setAnonymousToken('9f99054f-3205-426b-afc7-158d7ac3500f');
      })
      .controller('mainController', MainController)
      .service('dataService', dataService)
      .factory('commentsFactory', Comments);
    
    function MainController($scope, $http, Backand, dataService, commentsFactory) {
      var vm = this,
        comment = commentsFactory;
    
      vm.currentUserId = 1; //<<<< should be the current user later (no login yet)
    
      vm.displayedComments = {};
      dataService.getList('events').then(function(response) {
        vm.events = response.data;
      }); //eventsFactory;
    
    	vm.addEvent = function(newTitle) {
      	
        if (!newTitle) return; // don't add empty events
      	// this should be in a factory later
        var newDate = new Date();
        
        return $http({
            method: 'POST',
            url: Backand.getApiUrl() + '/1/objects/events?returnObject=true',
            data: {
              title: newTitle,
              created_at: newDate
            }
          }).then(function(response) {
          	//console.log(response, vm.events);
          	vm.events.data.push(response.data);
          });
      }
      vm.addComment = function(userId, event, text) {
        //event.comments.push(
        if (!text) return;
        
        comment.create(userId, event.id, text).then(function(response) {
          event.comments.push(response.data);
          //console.log(response);
        });
      }
    
      vm.getComments = commentsFactory.getComments;
      vm.showComment = function(event) {
        //console.log(event);
        commentsFactory.getComments(event.id).then(function(response) {
          vm.displayedComments[event.id] = !vm.displayedComments[event.id];
          event.comments = response.data;
        });
      };
      vm.remove = function(event, commentId) {
      	console.log('removing', event, commentId);
      	commentsFactory.delete(commentId).then(function(response){
        	//console.log('removed', response, event);
          // next update collection in angular
          event.comments = event.comments.filter(function(comment) {
          	return comment.id !== commentId; // remove comment
          });
        });
      }
    }
    
    function dataService($http, Backand) {
      var vm = this;
      //get the object name and optional parameters
      vm.getList = function(name, sort, filter) {
        return $http({
          method: 'GET',
          url: Backand.getApiUrl() + '/1/objects/' + name,
          params: {
            pageSize: 20,
            pageNumber: 1,
            filter: filter || '',
            sort: sort || ''
          }
        });
      }
    }
    
    function Comments($http, Backand) {
      return {
        create: function(user, event, text) {
          return $http({
            method: 'POST',
            url: Backand.getApiUrl() + '/1/objects/comments?returnObject=true',
            data: {
              event: event,
              user: user,
              text: text
            }
          });
        },
        delete: function(commentId) {
        	return $http({
            method: 'DELETE',
            url: Backand.getApiUrl() + '/1/objects/comments/' + commentId
          });
        },
        getComments: function(id) {
          return $http({
            method: 'GET',
            url: Backand.getApiUrl() + '/1/query/data/GetCommentsByEventId',
            params: {
              parameters: {
                eventId: id
              }
            }
          });
        }
      }
    }
    <link href="https://cdnjs.cloudflare.com/ajax/libs/ionic/1.2.4/css/ionic.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ionic/1.2.4/js/ionic.bundle.js"></script>
    <script src="https://cdn.backand.net/backand/dist/1.8.2/backand.min.js"></script>
    
    <div ng-app="demoApp" ng-controller="mainController as mainCtrl">
    
      <ion-header-bar align-title="center" class="bar-dark">
        <h1 class="title">EventsApp</h1>
       </ion-header-bar>
      <ion-content>
        <!--<pre>{{mainCtrl.events | json : 2}}</pre-->
        <!--<pre>{{mainCtrl.displayedComments|json:2}}</pre>-->
        <ion-list>
          <ion-item>
          <form ng-submit="mainCtrl.addEvent(mainCtrl.newEventTitle); mainCtrl.newEventTitle = '';">
            <input type="text" ng-model="mainCtrl.newEventTitle" placeholder="event title..."/>
            <button class="item item-icon-left">
              <i class="icon ion-plus-round"></i>
              add event
            </button>
          </form>
          </ion-item>
          <ion-item ng-if="mainCtrl.events.data.length === 0">
            <h1>
            There are no events yet.
            </h1>
          </ion-item>
          <ion-item ng-repeat="event in mainCtrl.events.data | orderBy: '-created_at'" class="item item-button-right">
            <h1>
              {{event.title}}
            </h1>
            <button ng-click="mainCtrl.showComment(event)" class="button icon-left ion-ios-chatbubble" title="{{mainCtrl.displayedComments[event.id]? 'hide comments': 'show comments'}}">
            </button>
            <div ng-show="mainCtrl.displayedComments[event.id]" class="list">
              
              <form ng-submit="mainCtrl.addComment(mainCtrl.currentUserId, event, commentText)">
                <label class="item item-input">
                  <span class="input-label">Username</span>
                  <input type="text" disabled ng-model="mainCtrl.currentUserId">
                </label>
                <label class="item item-input">
                  <span class="input-label">Comment</span>
                  <input type="text" ng-model="commentText">
                </label>
                <button class="button button-positive">
                   leave comment
                </button>
              </form>
              
              <ion-list>
                <ion-item ng-if="event.comments.length === 0">
                  <h2>
                  No comment yet. Be the first and leave a comment.
                  </h2>
                </ion-item>
                <ion-item ng-repeat="comment in event.comments">
                <div class="item item-button-right">
                user {{comment.user}} wrote {{comment.text}}
                  <button ng-click="mainCtrl.remove(event, comment.id)" class="button button-positive">
                  <i class="icon ion-ios-trash"></i>
                  </button>
                  </div>
                
                </ion-item>
              </ion-list>
            </div>
          </ion-item>
        </ion-list>
      </ion-content>
    </div>

    【讨论】:

      【解决方案3】:

      您还可以使用 ?deep=true 查询参数,在一对多的情况下将所有集合都带入。

      在您的示例中,/1/objects/event/1?deep=true 将返回 id=1 的事件的所有 cmets。

      var id = $stateParams.id;
      var useDeep = true;
      EventService.getEvent(id, useDeep).then(function(response){
        $scope.event = response.data;
        $scope.comments = response.data.comments;
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-05-27
        • 2012-11-25
        • 1970-01-01
        • 2017-07-06
        • 2021-03-15
        • 2021-07-14
        • 2010-11-05
        相关资源
        最近更新 更多