0

My question comes from the selected answer here

<ui-select-choices repeat="hero in getSuperheroes($select.search) | filter: $select.search">
<div ng-bind="hero"></div>

works perfectly fine with:

$scope.getSuperheroes = function(search) {
  var newSupes = $scope.superheroes.slice();
  if (search && newSupes.indexOf(search) === -1) {
    newSupes.unshift(search);
  }
  return newSupes;
}

However, when I put a breakpoint on $scope.superheroes I see its called as many times as my data. Data is very large. Its fetched from a $http.get() request and I'm handling not loading the data in the textbox all at once.

However, I don't want to call this until I actually start typing anything in the textbox. I tried to call getSuperheroes using

on-select="getSuperheroes($select.search)" 

and similarly

refresh="getSuperheroes($select.search)"

but they do not help allowing manual entry of data.

What do I use to call the function and yet get the task done just like how it works in the referenced answer?

Community
  • 1
  • 1
Gaurav Goenka
  • 152
  • 12

1 Answers1

1

I recommend you to do this:

  • In order to improve performance get rid of repeat="hero in getSuperheroes($select.search) | filter: $select.search", since if your data doesn't change the function getSuperheroes will be triggered (anyway) every time a $digest is executed (no matter the var newSupes changes or not in getSuperheroes) (that's wahat's happening right now!). Instead put (for instance) repeat="hero in myHeroes" and then in your getSuperheroes func do this:
$scope.getSuperheroes = function(search) {
    var aux = $scope.superheroes.slice();
    if (search && aux.indexOf(search) === -1) {
        aux.unshift(search);
    }
    $scope.myHeroes = aux;
}
  • Keep the refresh="getSuperheroes($select.search)", this will search the new values by calling getSuperheroes which will update the $scope.myHeroes var and then it will be refreshed in the view.
  • Add the property refresh-delay="500" (500 is just an example, put whatever fits your needs). This will delay the search that amount of milisecond. This is useful when you do not want start searching immediately. For instance if the user wants to search "Superman" and she/he type "Sup" in less than 500 milisec the search will start with the string "Sup". If you do not set that property the search would be executed 3 times (one for "S" another for "Su" and a third one for "Sup")

PS:

-- If you want to get the ui-select with some values initially, You must call the getSuperheroes func on your controller start.

-- You may need to declare $scope.myHeroes = []; at the beginning of your controller (it depends on your controller implementation).

-- You might want to read more info about $digest on the AngularJS official doc, on SO there are some related posts:

Community
  • 1
  • 1
lealceldeiro
  • 14,342
  • 6
  • 49
  • 80
  • I tried this and it works with one problem. Lets say I put in `some data` in my text box. It gets added to the drop down but then disappears when I hit enter. If I click the text box again, I can see `some data` and if I select it, this time it stays. – Gaurav Goenka Mar 01 '17 at 16:12
  • What do you mean with `I put in some data in my text box`? Yo mean you search, right? Are you using the `tagging` property? When you say you hit enter it's because you're trying to select one of the options? If so, check if this happens (disappear) as well when you select and option by clicking in it. – lealceldeiro Mar 01 '17 at 16:20
  • I can retain the value using `$scope.myHeroes.selected = $scope.myHeroes[0];` but that would display content even when the page loads, not after some user interaction. – Gaurav Goenka Mar 01 '17 at 16:20
  • If you do not want to display any data if the user hasn't interacted with the component then just initialise the `$scope.myHeroes.selected = null;`. This will show nothing on the ui-select (blank) – lealceldeiro Mar 01 '17 at 16:22
  • Yes, I mean search. No for tagging. (that would require multiple attribute also. Can't allow that). Enter = as you said selecting the searched option. It does not disappear, its just not the selected value until I click on the dropdown and manually select it again. – Gaurav Goenka Mar 01 '17 at 16:22
  • I think this is another issue. With your previous implementation...were you able to select an item as you described: by hitting enter? – lealceldeiro Mar 01 '17 at 16:25
  • Actually..I've always used this component this way, the user *must* click the desired option in order to get it selected or type exactly the "label" of the desired option and then hit enter – lealceldeiro Mar 01 '17 at 16:28
  • Yes I haven't had issues before. So this is what happens: 1) I enter new data. 2) Click the displaying new data in the drop down/ also try hitting enter (seperately). 3) The refresh function is again called. This time my search value becomes null as I haven't entered anything new. `$scope.myHeroes.selected = null;` executes. – Gaurav Goenka Mar 01 '17 at 16:30
  • OK, got it. Then I think this is a drawback of the approach I just described. If selecting an item by hitting enter is a condition this answer is not completely useful to you. :\ Sorry – lealceldeiro Mar 01 '17 at 16:36
  • No its not a drawback. I select an item using mouse or hit enter, problem is the refresh function is called a second time. It really shouldn't. I tried the same thing before I posted the question except I did `$scope.myHeroes.selected = aux` without realising `aux` is an array. Anyways, any thoughts on how to stop refresh from being called when selecting an object? – Gaurav Goenka Mar 01 '17 at 16:41
  • Oh, I see. I'm sorry, I missunderstood. Yeah, that's an issue I faced myself. I posted an edit to the answer that may be a hacky rather than a solution but if worked for me when using the ui-select. Tell me if it works for you. – lealceldeiro Mar 01 '17 at 16:50
  • Doesn't change a thing. :( – Gaurav Goenka Mar 01 '17 at 17:11
  • :( I've used that code and I can assure you this works. Do you have a **plnkr.co** or a **jsfiddle.net**? I could help you better with a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve), so I can reproduce exactly the situation. – lealceldeiro Mar 01 '17 at 17:39
  • There was a problem with my `ng-model`. I recommend you to remove the edit for `ui-select`. It works just fine without that. – Gaurav Goenka Mar 01 '17 at 18:24
  • Thanks a lot for the help on this :) – Gaurav Goenka Mar 01 '17 at 18:25
  • Well, those are great news! I'll update the answer and remove the edit. – lealceldeiro Mar 01 '17 at 18:28