【问题标题】:Display label displayed in options as the title of select显示选项中显示的标签作为选择的标题
【发布时间】:2019-06-23 14:29:06
【问题描述】:

如何在不使用java script 和更改ng-model 的情况下将option.Brand.Name 显示为select 字段的标题?

<select ng-model="detail.BrandId" title="" class="form-control" disabled>
    <option ng-repeat="option in mainCtrl.products" ng-selected="option.Id === detail.ProductId" ng-value="option.BrandId">{{option.Brand.Name}}</option>
</select>

【问题讨论】:

  • @Shaheryar.Akram 感谢您的建议,但对我来说没有用。
  • 只需使用 ng-attr-title="{{detail. Brand.Name}}"
  • @minaalfy 感谢您的建议,但我不想将 ng-model 更改为 'detail.Brand'
  • 您究竟为什么要这样做?这听起来更像是糟糕的设计。
  • 由于空间原因,上面的选择字段是表格中的众多字段之一,用户将无法立即查看“Brand.Name”,他们需要刷新才能查看通过工具提示查看它

标签: html angularjs angularjs-ng-repeat


【解决方案1】:

AngularJS 和选择选项

尝试在 select 元素本身内使用 ng-options AngularJS ngOptions directive。那么您就不需要使用ng-repeat 自己添加每个option 元素。

澄清

title-属性属于 select-元素,如果您将鼠标悬停在选择上就会显示。您希望标题显示当前选择的选项?我没听错吗?

如何将option.Brand.Name 显示为select 字段的title

很好奇,这个detail.ProductId 来自哪里?品牌是否由产品 ID 预选(查看您的代码)?

ng-selected="option.Id === detail.ProductId"

解决方案空间

您的要求/限制是:

  • 不使用 JavaScript(可能是因为您无法更改来源)
  • 无需更改 ng-model(因为某些数据库原因您只需要 BrandId

因此,由于选择元素的 title 无法访问其中的选项,因此设置它的唯一方法是取决于当前选择,即您的 detail.BrandId。所以title只能通过使用standard-angularJS方式动态设置(取决于当前选择),如:

预期行为

唯一通过选择更改的范围变量在选择的ng-model 中指定为detail.BrandId。这将在用户为其属性BrandId 选择option 时设置。当用户在选项之间进行选择时,它们将以BrandName 作为标签可见。选择后,此BrandName(选项标签)应显示为整个选择元素的标题

所以我们需要从detail.BrandId (selected ng-model) 到相关选项BrandName (因为这应该显示为标题)。

可能的解决方案

唯一的方法是使用标准的角度表达式/过滤器/数组索引来通过选定的detail.BrandId(ng-model)获取整个选项

然后我们可以在选中detail.BrandId === option.BrandId 后通过这个方程式查找option.BrandName

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

app.controller('mainCtrl', function($scope){
  $scope.products = [
    {Id: 0, name: 'Watson', brandId: 1, brandName:"IBM"},
    {Id: 1, name: 'DB2', brandId: 1, brandName:"IBM"},
    {Id: 2, name: 'Windows', brandId: 2, brandName: "Microsoft"},
    {Id: 3, name: 'Office', brandId: 2, brandName: "Microsoft"}
  ];
  $scope.detail = { ProductId: 3, BrandId: null };
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>

<!DOCTYPE html>
<html>
  <body data-ng-app="app" data-ng-controller="mainCtrl">
      <table border="1">
        <tr>
	  <th>Product Id</th><th>Product Name</th><th>Choose Brand</th><th>Brand Id</th>
        </tr>
        <tr>
          <td>{{detail.ProductId}}</td>
          <td>{{ (products | filter: {Id: detail.ProductId})[0].name }}</td>
          <td>
            <select class="form-control"
             ng-model="detail.BrandId" 
             ng-init="detail.BrandId = (products | filter: {Id: detail.ProductId})[0].brandId"
             ng-options="o.brandId as ('['+ o.Id +'] '+ o.name +' : '+ o.brandName  +' ('+ o.brandId +')') for o in products"
             title="{{ (products | filter: {brandId: detail.BrandId})[0].brandName}}"
            >
              <!-- default option when not preset by detail.ProductId-->
              <option value="">-- please choose brand --</option>
            </select>
        </td>
        <td>{{detail.BrandId}}</td>
      </tr>
    </table>

    <hr/>
      <p>Product is predefined. So the brand is pre-selected by product. BUT: after brand is selected, the product-details do NOT change!</p>
    Selected <strong>detail</strong>:
      <pre ng-model="selected">{{detail | json}}</pre>
   </body>
</html>

另见

有关使用 ng-options,另请参阅 plunkr example

【讨论】:

  • 我的问题中的选择被禁用,因为每当用户选择产品时它就会自动选择,这就是 ProductId 的来源。
【解决方案2】:

您可以使用 ng-repeat 提供的 as alias-expression 在 ng-repeat 父作用域中注册选择的选项对象。 在你的情况下,你只需要做这样的事情:

<select ng-model="detail.BrandId" 
        title="{{options | selectedProductFilter : detail.ProductId}}" 
        class="form-control" 
        disabled>
    <option ng-repeat="option in mainCtrl.products as options" 
            ng-selected="option.Id === detail.ProductId" 
            ng-value="option.BrandId">
        {{option.Brand.Name}}
    </option>
</select>

选项对象将在您的控制器闭包中可用,您可以使用自定义过滤器显示标题。

angular.module("app").filter('selectedProductFilter',
    function () {
        return function (input, id) {
            if (!input) return "";
            let occurence = input.filter(function (x) {
                return x.Id == id;
            });
            return occurence.length > 0 ? occurence[0].Brand.Name: "";
        }
    }
);

【讨论】:

  • 感谢您的建议,但“selectedOption”将包含所有“mainCtrl.products”,而不仅仅是选定的选项。
  • 你是对的。查看过滤器的使用情况。视野中很干净。
  • 谢谢 我从没想过使用这样的过滤器,但仅显示标题似乎很重。如果我找不到解决方案,我会考虑使用它。再次感谢。
【解决方案3】:

您需要在select 中执行ng-change 事件并在其中调用函数,将标签文本的值更改为选择值名称。像下面的东西 在 HTML 中

ng-change="changedValue(detail.BrandId)"

在 JS 中

$scope.changedValue = function(item) {
    //change label name here
  } 

【讨论】:

  • 感谢您发布建议的解决方案,但正如我在问题中指出的那样,我正在寻找不使用 javascript 的解决方案。
  • 您可以更改标签文本,您只需将标签与范围绑定,使您的标签类似于&lt;label for="MyField"&gt;{{ myFieldLabel }}&lt;/label&gt;,并添加此更改值函数$scope.myFieldLabel = item;
  • 谢谢,但我正在寻找没有 JS 中更改功能的解决方案。
【解决方案4】:

用“option”而不是“option.BrandId”填充 ng-model

然后你可以这样设置标题:

mainCtrl.products['ng-model-name'].Brand.Name

【讨论】:

  • 感谢您的建议,但我不想更改 ng-model,因为 BrandId 已连接到我的数据库。
  • 为此您可以在 ng-model 设置时使用 setter,更改品牌 ID
【解决方案5】:

以下是实现此目标的方法:

(function () {
	"use strict";
	const app = angular.module("app", []);
  
	app.controller("app.AppCtrl", $scope => {
    $scope.selectedOption = null;
    $scope.optionList = [{_id: 1, label: 'Option 1'}, {_id: 2, label: 'Option 2'}];
  });
  
})();
body {
  margin: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="app" ng-controller="app.AppCtrl">
	<select title="{{selectedOption.label}}" class="form-control" ng-model="selectedOption">
		<option ng-repeat="option in optionList" ng-value="option"> {{option.label}}</option>
	</select>
</div>

【讨论】:

  • 感谢您的建议,但我不想将 ng-model 更改为 'detail.Brand'
【解决方案6】:

尝试使用 ng-init

ng-init 添加到您的选择标签中,并将您希望默认选择的对象索引值。

例如 你的代码

<select ng-model="detail.BrandId" title="" class="form-control" disabled>
    <option ng-repeat="option in mainCtrl.products" ng-selected="option.Id === detail.ProductId" ng-value="option.BrandId">{{option.Brand.Name}}</option>
</select>

添加以下代码(假设我希望索引为 0):

ng-init="detail.BrandId = option[0].Brand.Name"

看起来像这样:

<select ng-model="detail.BrandId"  ng-init="detail.BrandId = option[0].Brand.Name" title="" class="form-control" disabled>
        <option ng-repeat="option in mainCtrl.products" ng-selected="option.Id === detail.ProductId" ng-value="option.BrandId">{{option.Brand.Name}}</option>
</select>

或检查这些线程的

how to use ng-option to set default value of select element

How to set default value in ng-options

【讨论】:

  • 感谢您的建议和链接线程。我检查了它们,但它对我不起作用。
  • 您遇到的任何错误或上述代码的任何其他问题?
  • Selected 并不总是在索引 0 处,并且使用 ng-init 会更改brandId。不过谢谢你的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
  • 1970-01-01
  • 2019-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多