如何处理嵌套数据 angularjs 和 rails?

How to work with nested data angularjs and rails?

我正在开发一个 rails 应用程序来管理和向朋友和家人展示图像。

在该应用程序中,您可以拥有

事件 -> 子事件 -> EventImages

routes.rb

resources :events do
  resources :subevents do
    resources :event_images
  end
end

当用户选择特定事件时,angularjs part/page 启动。

在活动编辑页面我想展示这样的子活动和图片:

Subevent1 -> Upload Images Button
  Image1 Image2 Image3 ...

Subevent2 -> Upload Images Button
  Image1 Image2 Image3 ...

...

New Subevent Button

所以基本上我想在一页上展示所有可用的子事件和每个子事件内的图像(可能有几个子事件和几个 100 张图像)。用户应该能够通过 drag/drop 添加新的子事件并上传或删除图像到每个子事件和子事件之间的移动图像。但是adding/deleting/uploading/mowing现在不是我的问题我只是提到它因为它可能会影响我的问题的解决方案。

我正在使用嵌套的 ng-repeat 来显示页面上的所有信息

  <div class="subevent" ng-repeat="subevent in event.subevents">
          <li class="img" ng-repeat="image in subevent.event_images">
          </li>
  </div>

我是 angular 世界的新手,现在我在如何检索上述页面所需的数据方面遇到了问题。

到目前为止我想到了两个想法:

通过嵌套形式的 api 控制器检索所有信息:

show.json.jbuilder

json.id @event.id
json.subevents @event.subevents do |subevent|
  json.id subevent.id
  json.name subevent.name
  json.event_images subevent.event_images do |event_image|
    json.id event_image.id
    json.thumb event_image.image({ resize: "150x150" }).url
  end
end

哪个会给我这个:

{
    "id": "54d75dd9686f6c2594020000",
    "subevents": [
        {
            "id": "54d75de1686f6c2594030000",
            "name": "Test",
            "event_images": [
                {
                    "id": "54df3904686f6c41cf0c0000",
                    "thumb": "/uploads/event_image/54df3904686f6c41cf0c0000/ebd83a10e03f9794f46cda02fdbc84d3.jpg"
                },
                {
                    "id": "54df56c5686f6c41cf850100",
                    "thumb": "/uploads/event_image/54df56c5686f6c41cf850100/ebd83a10e03f9794f46cda02fdbc84d3.jpg"
                }
            ]
        }
    ]
}

我正在使用 restangular 来检索此信息

$scope.event = Restangular.one('api/events','<%= @event.id %>').get().$object;

但我觉得这个解决方案不合适。当我开始操作页面(将新的 images/deleting images/moving 图像从一个子事件上传到另一个子事件时)我看到自己刷新了整个页面,因为我在这里看不到其他方法如何只删除一个图像例如无需重新加载完整的 $scope.event 即可获取更新后的页面。

我想到但到目前为止我还没有开始工作的另一个解决方案是使用 restangular 的嵌套功能来检索我的页面所需的所有信息,而无需创建单独的 api控制器。

$scope.event = Restangular.one("events",'<%= @event.id %>').all("subevents").all("event_images");

我找不到可以让我像上面那样用 ng-repeat 迭代 $scope.event 的工作解决方案,我不确定这是否能解决我的整体问题。

所以我想回答的问题是:

这将使用您当前的 API 回答您的第二个问题 Plunker

app.js

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
  $scope.event = {
      "id": "54d75dd9686f6c2594020000",
      "subevents": [
          {
              "id": "54d75de1686f6c2594030000",
              "name": "Test",
              "event_images": [
                  {
                      "id": "54df3904686f6c41cf0c0000",
                      "thumb": "/uploads/event_image/54df3904686f6c41cf0c0000/ebd83a10e03f9794f46cda02fdbc84d3.jpg"
                  },
                  {
                      "id": "54df56c5686f6c41cf850100",
                      "thumb": "/uploads/event_image/54df56c5686f6c41cf850100/ebd83a10e03f9794f46cda02fdbc84d3.jpg"
                  }
              ]
          }
      ]
    };
});
app.directive('myEvent', function(){
  return {
    scope: { myEvent: '=' },
    template: "<div>{{myEvent.id}}<div my-subevent='subevent' ng-repeat='subevent in myEvent.subevents'></div></div>",
    controller: function($scope){
      this.removeSubevent = function(e){
        $scope.myEvent.subevents.splice($scope.myEvent.subevents.indexOf(e), 1);
      };
    }
  };
});
app.directive('mySubevent', function(){
  return {
    scope: {mySubevent: '='},
    template: "<div>{{  mySubevent.name }} <a href='' ng-click='remove()'>remove subevent</a><div my-subevent-img='img' ng-repeat='img in mySubevent.event_images'></div></div>",
    require: '^myEvent',
    link: function(scope, ele, attrs, myEventCtrl){
      scope.remove = function(){
        myEventCtrl.removeSubevent(scope.subevent);
      };
    },
    controller: function($scope){
      this.removeImg = function(img){
         $scope.mySubevent.event_images.splice($scope.mySubevent.event_images.indexOf(img), 1);
      };
    }
  };
});
app.directive('mySubeventImg', function(){
  return {
    scope: { mySubeventImg: '=' },
    template: "<div><img ng-src='mySubeventImg.thumb'><a href ng-click='remove()'>remove img</a></div>",
    require: '^mySubevent',
    link: function(scope, ele, attrs, mySubeventCtrl){
      scope.remove = function(){
        mySubeventCtrl.removeImg(scope.mySubeventImg);
      };
    }

  };
});

index.html

<div my-event="event"></div>