Angular Material + TypeScript:自动完成 + 选择选项

Posted

技术标签:

【中文标题】Angular Material + TypeScript:自动完成 + 选择选项【英文标题】:Angular Material + TypeScript: Auto-complete + selecting option 【发布时间】:2015-12-29 00:33:25 【问题描述】:

目前我的代码有问题,如果我创建一个新芯片,它会命中我的标签模型并创建一个名称和 ID。

但是,当我键入以选择返回的选项时,如果单击该选项,它会返回一个对象,而不是标签名称。

这是 UI 的屏幕截图,其中 md-autocomplete 出现的下拉列表返回名称,创建一个仅显示名称的新标签,但单击 hotel 返回 "id":1,"name":"hotel"

我的问题是我只想返回名称,但不确定需要在哪里进行更改。

用户界面:

labels.html:

<md-content layout="column">
    <md-chips ng-model="cont.vm.selectedLabels" md-autocomplete-snap md-require-match="false" 
        md-on-append="cont.createLabel($chip)">
      <md-autocomplete
          md-selected-item="cont.vm.selectedItem"
          md-search-text="searchText"
          md-items="item in cont.querySearch(searchText)"
          md-item-text="item.name"
          md-min-length="2"
          placeholder="Type to add a label">
        <span md-highlight-text="cont.vm.searchText" >item.name</span>
           <md-not-found>
             No matches found.
            </md-not-found>       
      </md-autocomplete>
      <md-chip-template>
        <span>
          <strong>$chip.name</strong>
        </span>
      </md-chip-template>   
    </md-chips>
    <br />
    <p class="md-title">Existing Labels</p>
    <md-list>
      <md-list-item class="md-2-line label-option" ng-repeat="label in cont.vm.labels" layout="row"
          layout-wrap>
        <div class="md-item-text md-whiteframe-z1" flex>
          <h3>(NAME: label.name) (ID: label.id)</h3>
        </div>
      </md-list-item>
    </md-list>
</md-content>

labelsController.ts:

constructor(private $scope: common.IScope<LabelScope>, 
                private labelsService: ILabelsService)

                    super($scope);
                    this.vm.labels = this.loadLabels();
                    this.vm.selectedLabels = [];
                    this.vm.selectedItem = null;
                    this.vm.searchText = null;         
                    console.log($scope);           
             

            private loadLabels() 
                return this.labelsService.getLabels();
            
            // Returns list of labels that already exists
            public querySearch (query: string) 
                var results = query ? this.loadLabels() : [];
                return results;
                console.log(results);
                      
            // Returns name + ID on new chip created
            public createLabel($chip: string) 
                return 
                    name: $chip,
                    id: 4
                ;                                               
            

labelsService.ts:

 private mockLabels: Array<Label> = [
            new Label(1, 'hotel'),
            new Label(2, 'sport'),
            new Label(3, 'gaming'),
            new Label(4, 'apple'),
            new Label(5, 'retail')
        ];

        public getLabels() 
            return this.mockLabels;   
            console.log(this.mockLabels);         
        

【问题讨论】:

【参考方案1】:

不久前我遇到了同样的问题。原因是md-on-append 函数被调用,即使你从下拉列表中选择项目。

当您从下拉列表中选择一个项目时,它实际上会返回以下内容:


    name:
           name:hotel,
           id:1
    ,
    id:4

所以你应该稍微修改createLabel()函数的代码。

JS:

public createLabel($chip) 
    angular.forEach(this.vm.selectedLabels,function(element,index)
         if(element.name==$chip.name||element.name==$chip)
             this.vm.selectedLabels.splice(index,1);
         
    )
    if($chip.id==undefined)
         return 
           name: $chip,
           id: 4
         ;                                 
    
    else
        return $chip;
    

【讨论】:

伙计,你为我节省了几个小时的工作时间!我不知道在选择元素时会调用md-on-append!非常感谢!不过,我还有最后一个问题。然后我将如何增强此代码以防止多次选择“酒店”? IE。如何防止用户再次使用该标签? 这是一个错误。由于 id 的唯一性,它不允许您两次单击并插入相同的标签。 @RyanDrake 哈哈。我花了几个小时来弄清楚同样的事情。我很高兴能节省您的时间。你的第二个问题的答案,我也遇到了这个问题。在 md-on-append 中应用 angular.forEach 在芯片数组上并检查该元素是否存在,然后拼接该元素。然后返回相同的元素。没有其他选择。 呃,那段代码会是什么样子?我对 Typescript 很陌生,我不确定! 哦,我忘了您使用的是 Typescript。对不起老板,我不知道 TypeScript。我以为你在使用 AngularJS。反正逻辑是一样的。在芯片数组上应​​用 for 循环并检查 $chip.name 是否已经存在,然后从数组中删除该元素并返回 JSON。

以上是关于Angular Material + TypeScript:自动完成 + 选择选项的主要内容,如果未能解决你的问题,请参考以下文章

AngularCLI 和 Angular Material(原理图)错误:无法解析集合“@angular/material”

无法导入“@angular/material”模块

Angular2 Material:Angular 材质输入的自定义验证

Angular Material 设计

如何有效地使用 Angular Material 自定义调色板颜色 Angular Material

Angular 2 Material - 如何居中进度微调器