在ng-repeat中显示子数组

时间:2022-03-24 12:51:11

In my Angular app I have the following <select> element that is populated like so:

在我的Angular应用程序中,我有以下

HTML

<select name="device[ [[$index]] ]" ng-model="selectedModel" ng-change="loadModelImage(selectedModel)">
    <option value="">Model</option>
    <option ng-repeat="model in manufacturerModels" value="[[model.id]]">[[model.model]]</option>
</select>

JS

$scope.manufacturerModels = $filter('filter')($scope.models, {manufacturer_id: manufacturerId});

The above AngularJS snippet will return a JSON response of handset models stored in the API. (I'd post an example here but each object is quite lengthy).

上面的AngularJS代码段将返回存储在API中的手机模型的JSON响应。 (我会在这里发布一个例子,但每个对象都很冗长)。

Anyway, inside each 'model' is a sub-array of variants -- objects containing colours and memory sizes available for that device.

无论如何,每个'模型'内部都是变量的子数组 - 包含可用于该设备的颜色和内存大小的对象。

eg:

{
    model: "iPhone 6",
    manufacturer: "Apple",
    variants: [
        {
            color: "space grey",
            memory: "128GB"
        }
        {
            color: "gold",
            memory: "16GB"
        }
        {
            color: "space grey",
            memory: "64GB"
        }
    ]
}

The Goal

I'd like to know if it's possible (and if so, how) to populate the model dropdown's <option>'s with the variants in the name. So where it currently says [[model.model]] (.model being the name), I need each option to say something like: "iPhone 6 space grey 128GB"

我想知道是否有可能(如果是这样,如何)使用名称中的变体填充模型下拉列表的

PS. Angular interpolation temp. changed to [[ ]] due to the same pages using mustachePHP.

PS。角度插值温度。由于使用mustachePHP的相同页面,更改为[[]]。

3 个解决方案

#1


9  

I'm not sure I understand your question, but you can divide the models in optgroups and then have an option for each variant within each model:

我不确定我理解你的问题,但你可以在optgroups中划分模型,然后为每个模型中的每个变体选择一个:

<select>
        <option value="">Model</option>
        <optgroup ng-repeat="model in data" label="{{model.model}}">
          <option ng-repeat="variant in model.variants" value="{{model}}">{{ model.model + '-' + variant.color }}</option>
        </optgroup>
</select>

Please see this plunkr: http://plnkr.co/edit/rPNaGXEi0m9rvNkzQuBJ?p=preview

请看这个plunkr:http://plnkr.co/edit/rPNaGXEi0m9rvNkzQuBJ?p = preview

Alternatively, you have to flatten your array:

或者,您必须展平您的阵列:

$scope.flatten = function(){
      var out = [];
      angular.forEach($scope.data, function(d){
        angular.forEach(d.variants, function(v){
          out.push({model: d.model, variant: v.color})
        })
      })
      return out;
    }

And then you can use ngSelect:

然后你可以使用ngSelect:

<select ng-model="myColor" ng-options="model.variant group by model.model for model in flatten()">
   <option value=""> -- select -- </option>
</select>

Here's the updated Plnkr: http://plnkr.co/edit/rPNaGXEi0m9rvNkzQuBJ?p=preview

这是更新的Plnkr:http://plnkr.co/edit/rPNaGXEi0m9rvNkzQuBJ?p = preview

#2


3  

This may not be the answer you're looking for, but AngularJS is always pushing you to work with view-models, meaning models tailored for the views.

这可能不是您正在寻找的答案,但AngularJS总是推动您使用视图模型,这意味着为视图量身定制的模型。

Your example with the models & its nested variants is not a model which is tailored for the view you're trying to present, and so I would suggest creating a new model based on your current model.

您使用模型及其嵌套变体的示例不是针对您尝试呈现的视图而定制的模型,因此我建议您根据当前模型创建新模型。

This new model would have one entry per model per variant, and would be flat so that a single ng-repeat would easily iterate over them. You could even add a watch statement to "manufacturerModels", so that you can be sure the new model you create for the options ng-repeat is always up to date.

这个新模型每个变体每个模型有一个条目,并且是平的,因此单个ng重复很容易迭代它们。您甚至可以向“manufacturerModels”添加监视语句,以便确保为选项ng-repeat创建的新模型始终是最新的。

Another option, which would work with what you're trying to do would be to create a simple directive, which only copies its inner html without its tags, for example:

另一个选项,可以与您尝试做的一样,是创建一个简单的指令,它只复制其内部html而不包含其标签,例如:

<noTags>someHtml</noTags> --> someHtml

I'll leave it to you to write this directive, as its fairly simple.

我会留给你写这个指令,因为它非常简单。

Then, to solve your problem you'd simply need to write a nested ng-repeat statement, something like this:

然后,为了解决您的问题,您只需要编写一个嵌套的ng-repeat语句,如下所示:

<select name="device[ [[$index]] ]" ng-model="selectedModel" ng-change="loadModelImage(selectedModel)">
    <option value="">Model</option>
    <noTags ng-repeat="model in manufacturerModels">
        <option ng-repeat="varient in model.varients" value="[[model.id]]">[[model.model]] [[varient.color]] [[varient.memory]]</option>
    </noTags>
</select>

The rendered html should simply provide a long list of option tags which have all the options you want.

渲染的html应该只提供一长串选项标签,其中包含您想要的所有选项。

#3


-2  

You need to use the 'ngOptions' directive for that purpose. https://docs.angularjs.org/api/ng/directive/select The directive can take either an array of options or a hash (object) of options. And omit the 'ngRepeat' within 'option'.

您需要为此目的使用'ngOptions'指令。 https://docs.angularjs.org/api/ng/directive/select该指令可以采用选项数组或选项的哈希(对象)。并省略'选项'中的'ngRepeat'。

#1


9  

I'm not sure I understand your question, but you can divide the models in optgroups and then have an option for each variant within each model:

我不确定我理解你的问题,但你可以在optgroups中划分模型,然后为每个模型中的每个变体选择一个:

<select>
        <option value="">Model</option>
        <optgroup ng-repeat="model in data" label="{{model.model}}">
          <option ng-repeat="variant in model.variants" value="{{model}}">{{ model.model + '-' + variant.color }}</option>
        </optgroup>
</select>

Please see this plunkr: http://plnkr.co/edit/rPNaGXEi0m9rvNkzQuBJ?p=preview

请看这个plunkr:http://plnkr.co/edit/rPNaGXEi0m9rvNkzQuBJ?p = preview

Alternatively, you have to flatten your array:

或者,您必须展平您的阵列:

$scope.flatten = function(){
      var out = [];
      angular.forEach($scope.data, function(d){
        angular.forEach(d.variants, function(v){
          out.push({model: d.model, variant: v.color})
        })
      })
      return out;
    }

And then you can use ngSelect:

然后你可以使用ngSelect:

<select ng-model="myColor" ng-options="model.variant group by model.model for model in flatten()">
   <option value=""> -- select -- </option>
</select>

Here's the updated Plnkr: http://plnkr.co/edit/rPNaGXEi0m9rvNkzQuBJ?p=preview

这是更新的Plnkr:http://plnkr.co/edit/rPNaGXEi0m9rvNkzQuBJ?p = preview

#2


3  

This may not be the answer you're looking for, but AngularJS is always pushing you to work with view-models, meaning models tailored for the views.

这可能不是您正在寻找的答案,但AngularJS总是推动您使用视图模型,这意味着为视图量身定制的模型。

Your example with the models & its nested variants is not a model which is tailored for the view you're trying to present, and so I would suggest creating a new model based on your current model.

您使用模型及其嵌套变体的示例不是针对您尝试呈现的视图而定制的模型,因此我建议您根据当前模型创建新模型。

This new model would have one entry per model per variant, and would be flat so that a single ng-repeat would easily iterate over them. You could even add a watch statement to "manufacturerModels", so that you can be sure the new model you create for the options ng-repeat is always up to date.

这个新模型每个变体每个模型有一个条目,并且是平的,因此单个ng重复很容易迭代它们。您甚至可以向“manufacturerModels”添加监视语句,以便确保为选项ng-repeat创建的新模型始终是最新的。

Another option, which would work with what you're trying to do would be to create a simple directive, which only copies its inner html without its tags, for example:

另一个选项,可以与您尝试做的一样,是创建一个简单的指令,它只复制其内部html而不包含其标签,例如:

<noTags>someHtml</noTags> --> someHtml

I'll leave it to you to write this directive, as its fairly simple.

我会留给你写这个指令,因为它非常简单。

Then, to solve your problem you'd simply need to write a nested ng-repeat statement, something like this:

然后,为了解决您的问题,您只需要编写一个嵌套的ng-repeat语句,如下所示:

<select name="device[ [[$index]] ]" ng-model="selectedModel" ng-change="loadModelImage(selectedModel)">
    <option value="">Model</option>
    <noTags ng-repeat="model in manufacturerModels">
        <option ng-repeat="varient in model.varients" value="[[model.id]]">[[model.model]] [[varient.color]] [[varient.memory]]</option>
    </noTags>
</select>

The rendered html should simply provide a long list of option tags which have all the options you want.

渲染的html应该只提供一长串选项标签,其中包含您想要的所有选项。

#3


-2  

You need to use the 'ngOptions' directive for that purpose. https://docs.angularjs.org/api/ng/directive/select The directive can take either an array of options or a hash (object) of options. And omit the 'ngRepeat' within 'option'.

您需要为此目的使用'ngOptions'指令。 https://docs.angularjs.org/api/ng/directive/select该指令可以采用选项数组或选项的哈希(对象)。并省略'选项'中的'ngRepeat'。