【问题标题】:angularstrap typeahead with json object array is not working带有json对象数组的angularstrap typeahead不起作用
【发布时间】:2013-07-09 06:53:04
【问题描述】:

我正在使用 angularstrap typeahead 指令。它适用于单个对象 json 值,但在用我的 json 对象数组替换 json 时不起作用。

演示Json:

typeahead= ["Alabama","Alaska","Arizona","Arkansas","California","Colorado","Connecticut","Delaware","Florida","Georgia"];
<input type="text" ng-model="typeaheadValue" bs-typeahead="typeahead">

以上代码运行良好。

我的 JSON 对象数组:

typeahead = [
    {id: 1, name: 'name1', email: 'email1@domain.com'},
    {id: 2, name: 'name2', email: 'email2@domain.com'},
    {id: 3, name: 'name3', email: 'email3@domain.com'}
];

$scope.typeaheadFn = function(query) {
   return $.map($scope.typeahead, function(contacts) {
      return contacts;
   });
}
<input type="text" ng-model="typeaheadValue" bs-typeahead="typeaheadFn">

请给我一些解决方案。

【问题讨论】:

    标签: bootstrap-typeahead angular-strap


    【解决方案1】:

    您想将您的项目映射到字符串列表,我相信。

    试试:

    $scope.typeaheadFn = function(query) {
        return $.map($scope.typeahead, function(contact) {
            return contact.name;
        });
    }
    

    (我应该补充一点,我目前被类似的东西难住了)

    【讨论】:

      【解决方案2】:

      如果你有,例如:

      items = [
          {id: 1, name: 'name1', email: 'email1@domain.com'},
          {id: 2, name: 'name2', email: 'email2@domain.com'},
          {id: 3, name: 'name3', email: 'email3@domain.com'}
      ];
      

      你需要:

      <input type="text" bs-typeahead ng-model="selectedItem" ng-options="item.name for item in items|orederBy:'name'|filter:{name:$viewValue}:optionalCompareFn"></input>
      

      如果您从 ng-options 中排除过滤器,将对项目对象的每个属性进行匹配,因此如果您希望对一个属性进行匹配,请添加 filter:{propName:$viewValue}。此外,如果您排除optionalCompareFn,则将应用来自角度的默认比较,但您可以添加您的自定义比较(在您的$scope 上),并带有签名(actual 是项目的属性值,在过滤器中说明,而不是整个对象)。

      optionalCompareFn(expected,actual){ return /compare and return true or false/}
      

      【讨论】:

        【解决方案3】:

        尝试 1

        在经历了巨大的挫折之后,我终于得到了这个半成品。

        显示所需文本的一种简单方法是为每个项目设置一个toString 方法。

        你可能有类似的东西

        typeaheadData = [
          {id: 1, text: "abc", toString: function() { return "abc"; }},
          {id: 2, text: "def", toString: function() { return "def"; }}
        ]
        

        然后您将在弹出的选项中看到正确的文本,但匹配还不能正常工作(小部件显示的项目与用户在框中输入的文本不匹配)。

        为了让这项工作正常进行,我使用了新的 filter 选项,该选项已添加到当前 git 版本的 angular-strap 中。请注意,它甚至不在存储库中预构建的 dist/angular-strap.js 文件中,您需要自己重建此文件才能获得新功能。 (截至提交 ce4bb9de6e53cda77529bec24b76441aeaebcae6)。

        如果您的 bs-typeahead 小部件如下所示:

        <input bs-typeahead ng-options="item for item in items" filter="myFilter" ng-model="myModel" />
        

        然后,只要用户输入一个键,就会调用过滤器myFilter。它使用两个参数调用,第一个是您传递给typeahead 的整个列表,第二个是输入的文本。然后,您可以遍历列表并返回您想要的项目,可能通过检查文本是否与项目的一个或多个属性匹配。所以你可以像这样定义过滤器:

        var myApp = angular.module('myApp', ['mgcrea.ngStrap'])
          .filter('myFilter', function() {
            return function(items, text) {
              var a = [];
              angular.forEach(items, function(item) {
                // Match an item if the entered text matches its `text` property.
                if (item.label.indexOf(text) >= 0) {
                  a.push(item);
                }
              });
              return a;
            };
          });
        

        不幸的是,这仍然不太正确;如果您通过单击选择一个项目,则 text 参数将是项目列表中的实际对象,而不是文本。

        尝试 2

        我仍然觉得这太烦人了,所以我创建了一个 angular-strap (https://github.com/amagee/angular-strap) 的分支,它可以让你这样做:

        typeaheadData = [
          {id: 1, text: "abc"},
          {id: 2, text: "def"}
        ]
        
        //...
        
        $scope.myFormatter = function(id) {
           if (id == null) { return; }
           typeaheadData.forEach(function(d) { 
               if (d.id === id) { 
                   return d.text; 
               }
           });
        };
        
        <input bs-typeahead ng-options="item for item in items" ng-model="myModel" 
          key-field="id" text-field="text" formatter="myFormatter" />
        

        无需对toString 方法或过滤器大惊小怪。 text-field 是用户看到的内容,key-field 是写入模型的内容。

        (不!如果您在不通过视图的情况下更新模型仍然不起作用)。

        formatter 选项是必需的,因此当您将模型值设置为仅关键字段时,小部件可以找出要显示的正确文本。

        【讨论】:

        • key-field="id" text-field="text" 这不起作用。如果您确定,请为它制作 fiddlw。
        猜你喜欢
        • 1970-01-01
        • 2016-04-03
        • 1970-01-01
        • 2014-11-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多