【问题标题】:AngularJS: multi dimensional array $scopeAngularJS:多维数组 $scope
【发布时间】:2017-05-08 22:34:27
【问题描述】:

这是场景

我有这个标记,我想根据 API 返回的数组的 $scope 循环它

<div class="car-group" ng-repeat="p in photos">
    <input type="text" name="product_description" id="product_description" class="form-control product_description" ng-model="p.product_description">

    <div class="car-photos">
        <input type="text" name="photo_label" class="form-control photo label" ng-model="p.photo_label">
        <input type="text" name="photo_label" class="form-control photo label" ng-model="p.image_data">
    </div>  
</div>

JSON

$scope.photos = [
                  [
                       {"photo_label":"Cover","image_data":"cover.jpg"},
                       {"product_description":"Car Cover"}
                  ],

                  [
                       {"photo_label":"Inside","image_data":"inside.jpg"},
                       {"photo_label":"Rear","image_data":"rear.jpg"},
                       {"product_description":"Car View"}
                  ]
               ]

这是我想要做什么的插图

照片的数量取决于来自服务器的 JSON 响应。

【问题讨论】:

  • 可以改变json的结构吗?
  • 您能否提供更多关于图像数量如何决定每个图像框宽度的信息?
  • @ndoes.. 改变 json 结构??你的意思是?对不起,我很困惑..
  • 对象包含不同的属性。循环是可能的,但您认为会有一堆条件语句。构造 JSON like this 更有意义。

标签: javascript angularjs arrays


【解决方案1】:

Here I added Demo

Hi

我把你的 json 对象改成了这种格式:

$scope.photos = [
                      {"product_description":"Car Cover",
                        "images":
                        [
                             {"photo_label":"Cover","image_data":"cover.jpg"}

                        ]},


                            {"product_description":"Car View",
                        "images":
                            [
                             {"photo_label":"Inside","image_data":"inside.jpg"},
                             {"photo_label":"Rear","image_data":"rear.jpg"}
                        ]}

                     ]

【讨论】:

    【解决方案2】:

    首先我们这里有一个非常错误的数据结构,我假设它不能被改变,所以我将展示将这个结构转换为更准确的解决方案。为什么这个结构是错误的:

    • 单元素数组具有元素的动态计数
    • 单个元素是具有不同类型的对象的数组 - 而数组是用于存储相同类型元素的结构。目前我们在同一个数组中有照片对象和产品属性对象。

    为了解决这个问题,我们需要将产品道具与照片分开,我的建议是将单元素数组转换为对象:

    {
    "photos": [
      {
        "photo_label": "Inside",
        "image_data": "inside.jpg"
      },
      {
        "photo_label": "Rear",
        "image_data": "rear.jpg"
      }
    ],
    "product_description": "Car View"
    }
    

    我们可以认为这个对象代表产品属性,照片就是其中之一。我认为产品也是更好的命名方式,因为照片只是产品道具。

    好的,所以我已经准备好了带有转换功能的工作解决方案。

    var app = angular.module("app",[]);
    app.controller("controller", function($scope){
    
      //server structure
      var products = [
        [
          {"photo_label":"Cover","image_data":"cover.jpg"},
          {"product_description":"Car Cover"}
        ],
        [
          {"photo_label":"Inside","image_data":"inside.jpg"},
          {"photo_label":"Rear","image_data":"rear.jpg"},
          {"product_description":"Car View"}
        ]
      ];
      
      //function coverting structure to better one
      function _convertToProperStructure(arr){
        
        return arr.map(function(el){
          
          var properEl={ 'photos': [] };
          
          //last element is description so without it
          for ( var i=0; i< el.length-1; i++ ){
            
            properEl.photos.push(el[i]);//add photo
            
          }
          
          //set description
          properEl.product_description = el[el.length-1].product_description;
          
          return properEl;
        });
        
      };
      
      //convert to proper structure
      $scope.products=_convertToProperStructure(products);
      
    });
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <div ng-app="app" ng-controller="controller">
    <div  class="car-group" ng-repeat="p in products">
        <input type="text" name="product_description" id="product_description" class="form-control product_description" ng-model="p.product_description">
    
        <div class="car-photos" ng-repeat="p in p.photos">
            <input type="text" name="photo_label" class="form-control photo label" ng-model="p.photo_label">
            <input type="text" name="photo_label" class="form-control photo label" ng-model="p.image_data">
        </div>  
    </div>
    </div> 

    【讨论】:

    • @KimCarlo 太棒了!我有什么不清楚 - 问问吧。
    【解决方案3】:

    可能看起来有点笨拙 - 但也许是这样的?

    <div class="car-group" ng-repeat="p in photos">
        <div ng-repeat="elt in p | filter: myDesc">
            <input type="text" name="product_description" id="product_description" class="form-control product_description" ng-model="elt.product_description">
        </div>
    
        <div ng-repeat="elt in p | filter: myImage">
            <div class="car-photos">
                <input type="text" name="photo_label" class="form-control photo label" ng-model="elt.photo_label">
                <input type="text" name="photo_label" class="form-control photo label" ng-model="elt.image_data">
            </div>  
        </div>
    

    在哪里

    $scope.myDesc = function(elt){
        if (elt.product_description){
            return true;
        } else{
            return;
        }
    };
    
    $scope.myImage = function(elt){
        if (elt.photo_label || elt.image_data){
            return true;
        } else{
            return;
        }
    };
    

    【讨论】:

      【解决方案4】:

      您可以将您的 json 对象 缩减为这种格式:

      [
        {
          "images": [
            {
              "photo_label": "Cover",
              "image_data": "cover.jpg"
            }
          ],
          "product_description": "Car Cover"
        },
        {
          "images": [
            {
              "photo_label": "Inside",
              "image_data": "inside.jpg"
            },
            {
              "photo_label": "Rear",
              "image_data": "rear.jpg"
            }
          ],
          "product_description": "Car View"
        }
      ]
      

      使用 ng-repeat 内的 ng-repeat 以更轻松地与您的标记进行数据绑定

      请看下面的演示:

      angular.module("app", []).controller("ctrl", function($scope) {
      
        $scope.photos = [
          [{
            "photo_label": "Cover",
            "image_data": "cover.jpg"
          }, {
            "product_description": "Car Cover"
          }],
          [{
            "photo_label": "Inside",
            "image_data": "inside.jpg"
          }, {
            "photo_label": "Rear",
            "image_data": "rear.jpg"
          }, {
            "product_description": "Car View"
          }]
        ].reduce(function(p, c) {
          let obj = {};
          c.forEach(function(e) {
            if (e['product_description']) {
              obj['product_description'] = e['product_description'];
            } else {
              obj['images'] = obj['images'] || [];
              obj['images'].push({
                "photo_label": e['photo_label'],
                "image_data": e['image_data']
              });
            }
          });
          p.push(obj);
          return p;
        }, []);
      
        // console.log($scope.photos);
      });
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
      
      <div ng-app="app" ng-controller="ctrl">
      
        <div class="car-group" ng-repeat="p in photos">
          <input type="text" name="product_description" id="product_description" class="form-control product_description" ng-model="p.product_description">
      
          <div class="car-photos" ng-repeat="img in p.images">
            <input type="text" name="photo_label" class="form-control photo label" ng-model="img.photo_label">
            <input type="text" name="photo_label" class="form-control photo label" ng-model="img.image_data">
          </div>
        </div>
      
      </div>

      【讨论】:

        猜你喜欢
        • 2013-11-23
        • 2017-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多