为什么angular ui.select不更新模型?

时间:2015-11-17 12:08:23

标签: javascript angularjs model lodash ui-select

我想创建通用搜索/选择框来过滤某些列表。 但UI.SELECT不更新模型。

过滤工作。添加项目到列表工作。模型仍然是空的。

也许我对lodash做错了。

所选项目在条形图中可见,但模型为空。

screen

  app = angular.module('commission', ['ui.select', 'ngSanitize', 'ui.bootstrap']);

  app.config([
    '$compileProvider',
    function( $compileProvider )
    {
        $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|data|ftp|mailto|chrome-extension):/);
    }
  ]);

  app.controller('MainController', function($scope, $http, $interval, $timeout, $uibModal, $log, $templateCache){
    self = this;

    self.items1 = _.indexBy(_.map([{"id": 1, "name": "Item11"}, {"id": 2, "name": "Item12"}], function(o) {o.class="info"; return o;}), function(o) {return 't' + o.id; });
    self.items2 = _.indexBy(_.map([{"id": 125, "name": "Item21"}, {"id": 2, "name": "Item22"}], function(o) {o.class="success"; return o;}), function(o) {return 's' + o.id; });
    self.items3 = _.indexBy(_.map([{"id": 1, "name": "Item31"}, {"id": 2, "name": "Item32"}, {"id": 3, "name": "Item33"}, {"id": 4, "name": "Item34"}], function(o) {o.class="warning"; return o;}), function(o) {return 'p' + o.id; });

    self.filter_by =  _.assign({}, self.items1, self.items2, self.items3);

    $scope.list = [];
    $scope.search_bar = [];
    $scope.count = 0;
    self.page = 1;

    // $scope.search_bar = [];

    /**
     * prepare request and update commissions list
     * @param  {Object} filter filtering params
     * @return {none}        Updates $scope object
     */
    function filterList(search){
      console.log("filterList"); 
      // params = {};
      // angular.forEach(filter, function(value, key) {
      //   if (value.length){
      //     params[key] = value.map(function(o){return o.id});
      //   }
      // });
      $http.post('', {action: 'filter', search: search, page: self.page})
        .then(function(response){
          delete $scope.list;
          $scope.list = response.data.list;
          $scope.count = response.data.count;
        });
    }

    /**
     * Filter debounce option. For decrease unusefull requests.
     * @param  {object} filter filter object for filterList function.
     * @param  {bool} true      recursive watching
     * @return {none}
     */
    var timer = {};
    $scope.$watch('search_bar', function (search){
      console.log("scope watch search");
      $timeout.cancel(timer) || false;
      timer = $timeout(filterList, 1500, true, search)
    }, true)

    self.gotopage = function (){
      filterList($scope.search_bar);
    }
  })


  app.filter('oFilter', function () {
    return function (obj, search) {
      if (search){
        return _.toArray(_.filter(obj, function(val){
          return val.name.toLowerCase().indexOf(search.toLowerCase()) !== -1 || parseInt(search) === val.id;
        }));
      }
      return []
    };
  });

  app.filter('omnibox', function () {
    return _.memoize(function (obj, search){
      var fields = ['min', 'max', 'convertation'],
        actions = ['>=', '<=', '=', '>', '<'],
        NOT = false,
        str_in = function (str, arr) {
          _.forEach(arr, function(o){
            if (str.search(o) !== -1) return true
          })
        }

      if (search){
        if (search.charAt(0) === "!"){  // clear "!" -- NOT from search;
          search = search.substr(1);
          NOT = true;
        }
        search = search.trim()

        ret_arr = _.toArray(_.filter(obj, function(val){
          return val.name.toLowerCase().indexOf(search.toLowerCase()) !== -1 || parseInt(search) === val.id;
        }));

          field = _.find(fields, function(o) {return this.search(o) !== -1}, search);
          action = _.find(actions, function(o) {return this.search(o) !== -1}, search);
          data = (search.match(/\d+(?:\.\d+)?/) || [''])[0];
          data = (data.search('.')=== -1 ? parseInt(data) : parseFloat(data, 10)) || null;
          // console.log(field, action, data);
          if ((field || action) && data !== null){
            if (!field) {
              _.forEach(fields, function(f){
                ret_arr.unshift({
                  class: "danger",
                  id: action + " " + data,
                  name: f,

                });
              });
            } else if (!action) {
              _.forEach(actions, function(a){
                ret_arr.unshift({
                  class: "danger",
                  id: a + " " + data,
                  name: field,

                });
              });
            } else {
              ret_arr.unshift({
                class: "danger",
                id: action + " " + data,
                name: field,

              });
            }

          }

        ret_arr = _.map(ret_arr, function(o){o.not = NOT; return o;});
        return _.clone(ret_arr, true);
      }
      return _.map(_.toArray(obj), function(o){o.not = false; return o;});
    }, function (obj, search) { return obj.length + search });
  });
<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script data-require="jquery@*" data-semver="2.1.4" src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
    <script data-require="angular.js@1.4.x" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js" data-semver="1.4.7"></script>
    <link data-require="ui-select@*" data-semver="0.11.1" rel="stylesheet" href="https://github.com/angular-ui/ui-select/blob/master/dist/select.css" />
    <link data-require="bootstrap@*" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
    <link data-require="bootstrap@*" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootswatch/3.3.5/cosmo/bootstrap.min.css" />
    <link data-require="bootstrap@*" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" />
    <script data-require="bootstrap@*" data-semver="3.3.5" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <script data-require="ui-select@*" data-semver="0.11.1" src="https://rawgit.com/angular-ui/ui-select/master/dist/select.js"></script>
    <script data-require="lodash.js@*" data-semver="3.10.0" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular-sanitize.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.14.3/ui-bootstrap.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.14.3/ui-bootstrap-tpls.min.js"></script>
    <link rel="stylesheet" href="https://github.com/almasaeed2010/AdminLTE/blob/master/dist/css/AdminLTE.min.css" />
    <link rel="stylesheet" href="style.css" />
    <script src="app.js"></script>
  </head>

  <body>
    
    <section class="content" ng-app="commission" ng-controller="MainController as ctrl">
      <span>try: "<= 150"</span>
      <ui-select class="form-control" multiple="" ng-model="search_bar" theme="bootstrap" title="Omnibox] Hi there, try put some chars">
        <ui-select-match placeholder="Select o...">
          <i class="fa fa-exclamation" ng-show="$item.not"></i>
          <span ng-bind="$item.name"></span>
          <span ng-bind="$item.id" class="label label-{[{$item.class}]}"></span>
        </ui-select-match>
        <ui-select-choices repeat="o in ctrl.filter_by | omnibox: $select.search">
          <i class="fa fa-exclamation" ng-show="o.not"></i>
          <span ng-bind="o.name"></span>
          <span ng-bind="o.id" class="label pull-right label-{[{o.class}]}"></span>
        </ui-select-choices>
      </ui-select>
      <br />MODEL: <span ng-bind="search_bar | json: '2'">
    </section>
  </body>

</html>

1 个答案:

答案 0 :(得分:0)

equilerex answer on github

Working demo

  

只需使用$scope.someModel.search_bar代替$scope.search_bar