最新服务器上的版本,以后用这个
wangzhenxin
2023-11-19 bc164b8bdbfbdf1d8229a5ced6b08d7cb8db7361
commit | author | age
2207d6 1 Migrating to typeahead.js v0.10.0
W 2 =================================
3
4 Preamble
5 --------
6
7 v0.10.0 of typeahead.js ended up being almost a complete rewrite. Many things 
8 stayed the same, but there were a handful of changes you need to be aware of 
9 if you plan on upgrading from an older version. This document aims to call out 
10 those changes and explain what you need to do in order to have an painless 
11 upgrade.
12
13 Notable Changes
14 ----------------
15
16 ### First Argument to the jQuery Plugin
17
18 In v0.10.0, the first argument to `jQuery#typeahead` is an options hash that
19 can be used to configure the behavior of the typeahead. This is in contrast
20 to previous versions where `jQuery#typeahead` expected just a series of datasets
21 to be passed to it:
22
23 ```javascript
24 // pre-v0.10.0
25 $('.typeahead').typeahead(myDataset);
26
27 // v0.10.0
28 $('.typeahead').typeahead({
29   highlight: true,
30   hint: false
31 }, myDataset);
32 ```
33
34 If you're fine with the default configuration, you can just pass `null` as the 
35 first argument:
36
37 ```javascript
38 $('.typeahead').typeahead(null, myDataset);
39 ```
40
41 ### Bloodhound Suggestion Engine
42
43 The most notable change in v0.10.0 is that typeahead.js has been decomposed into
44 a suggestion engine and a UI view. As part of this change, the way you configure
45 datasets has changed. Previously, a dataset config would have looked like:
46
47 ```javascript
48 {
49   valueKey: 'num',
50   local: [{ num: 'one' }, { num: 'two' }, { num: 'three' }],
51   prefetch: '/prefetch',
52   remote: '/remote?q=%QUERY'
53 }
54 ```
55
56 In v0.10.0, an equivalent dataset config would look like:
57
58 ```javascript
59 {
60  displayKey: 'num',
61  source: mySource
62 }
63 ```
64
65 As you can see, `local`, `prefetch`, and `remote` are no longer defined at the 
66 dataset level. Instead, all you set in a dataset config is `source`. `source` is
67 expected to be a function with the signature `function(query, callback)`. When a
68 typeahead's query changes, suggestions will be requested from  `source`. It's
69 expected `source` will compute the suggestion set and invoke `callback` with an array
70 of suggestion objects. The typeahead will then go on to render those suggestions.
71
72 If you're wondering if you can still configure `local`, `prefetch`, and 
73 `remote`, don't worry, that's where the Bloodhound suggestion engine comes in.
74 Here's how you would define `mySource` which was referenced in the previous 
75 code snippet:
76
77 ```
78 var mySource = new Bloodhound({
79   datumTokenizer: function(d) { 
80     return Bloodhound.tokenizers.whitespace(d.num); 
81   },
82   queryTokenizer: Bloodhound.tokenizers.whitespace,
83   local: [{ num: 'one' }, { num: 'two' }, { num: 'three' }],
84   prefetch: '/prefetch',
85   remote: '/remote?q=%QUERY'
86 });
87
88 // this kicks off the loading and processing of local and prefetch data
89 // the suggestion engine will be useless until it is initialized
90 mySource.initialize();
91 ```
92
93 In the above snippet, a Bloodhound suggestion engine is initialized and that's 
94 what will be used as the source of your dataset. There's still one last thing
95 that needs to be done before you can use a Bloodhound suggestion engine as the 
96 source of a dataset. Because datasets expect `source` to be function, the 
97 Bloodhound instance needs to be wrapped in an adapter so it can meet that 
98 expectation.
99
100 ```
101 mySource = mySource.ttAdapter();
102 ```
103
104 Put it all together:
105
106 ```javascript
107 var mySource = new Bloodhound({
108   datumTokenizer: function(d) { 
109     return Bloodhound.tokenizers.whitespace(d.num); 
110   },
111   queryTokenizer: Bloodhound.tokenizers.whitespace,
112   local: [{ num: 'one' }, { num: 'two' }, { num: 'three' }],
113   prefetch: '/prefetch',
114   remote: '/remote?q=%QUERY'
115 });
116
117 mySource.initialize();
118
119 $('.typeahead').typeahead(null, {
120   displayKey: 'num',
121   source: mySource.ttAdapter()
122 });
123 ```
124
125 ### Tokenization Methods Must Be Provided
126
127 The Bloodhound suggestion engine is token-based, so how datums and queries are
128 tokenized plays a vital role in the quality of search results. Pre-v0.10.0,
129 it was not possible to configure the tokenization method. Starting in v0.10.0,
130 you **must** specify how you want datums and queries tokenized. 
131
132 The most common tokenization methods split a given string on whitespace or 
133 non-word characters. Bloodhound provides implementations for those methods
134 out of the box:
135
136 ```javascript
137 // returns ['one', 'two', 'twenty-five']
138 Bloodhound.tokenizers.whitespace('  one two  twenty-five');
139
140 // returns ['one', 'two', 'twenty', 'five']
141 Bloodhound.tokenizers.nonword('  one two  twenty-five');
142 ```
143
144 For query tokenization, you'll probably want to use one of the above methods.
145 For datum tokenization, this is where you may want to do something a tad bit
146 more advanced.
147
148 For datums, sometimes you want tokens to be dervied from more than one property. 
149 For example, if you were building a search engine for GitHub repositories, it'd 
150 probably be wise to have tokens derived from the repo's name, owner, and 
151 primary language:
152
153 ```javascript
154 var repos = [
155   { name: 'example', owner: 'John Doe', language: 'JavaScript' },
156   { name: 'another example', owner: 'Joe Doe', language: 'Scala' }
157 ];
158
159 function customTokenizer(datum) {
160   var nameTokens = Bloodhound.tokenizers.whitespace(datum.name);
161   var ownerTokens = Bloodhound.tokenizers.whitespace(datum.owner);
162   var languageTokens = Bloodhound.tokenizers.whitespace(datum.language);
163
164   return nameTokens.concat(ownerTokens).concat(languageTokens);
165 }
166 ```
167
168 There may also be the scenario where you want datum tokenization to be performed
169 on the backend. The best way to do that is to just add a property to your datums 
170 that contains those tokens. You can then provide a tokenizer that just returns 
171 the already existing tokens:
172
173 ```javascript
174 var sports = [
175   { value: 'football', tokens: ['football', 'pigskin'] },
176   { value: 'basketball', tokens: ['basketball', 'bball'] }
177 ];
178
179 function customTokenizer(datum) { return datum.tokens; }
180 ```
181
182 There are plenty of other ways you could go about tokenizing datums, it really
183 just depends on what you are trying to accomplish.
184
185 ### String Datums Are No Longer Supported
186
187 Dropping support for string datums was a difficult choice, but in the end it
188 made sense for a number of reasons. If you still want to hydrate the suggestion 
189 engine with string datums, you'll need to use the `filter` function:
190
191 ```javascript
192 var engine = new Bloodhound({
193   prefetch: {
194     url: '/data',
195     filter: function(data) {
196       // assume data is an array of strings e.g. ['one', 'two', 'three']
197       return $.map(data, function(str) { return { value: str }; });
198     },
199     datumTokenizer: function(d) { 
200       return Bloodhound.tokenizers.whitespace(d.value); 
201     },
202     queryTokenizer: Bloodhound.tokenizers.whitespace
203   }
204 });
205 ```
206
207 ### Precompiled Templates Are Now Required
208
209 In previous versions of typeahead.js, you could specify a string template along
210 with the templating engine that should be used to compile/render it. In 
211 v0.10.0, you can no longer specify templating engines; instead you must provide
212 precompiled templates. Precompiled templates are functions that take one 
213 argument: the context the template should be rendered with. 
214
215 Most of the popular templating engines allow for the creation of precompiled 
216 templates. For example, you can generate one using Handlebars by doing the
217 following:
218
219 ```javascript
220 var precompiledTemplate = Handlebars.compile('<p>{{value}}</p>');
221 ```
222
223 [Handlebars]: http://handlebarsjs.com/
224
225 ### CSS Class Changes
226
227 `tt-is-under-cursor` is now `tt-cursor` - Applied to a hovered-on suggestion (either via cursor or arrow key).
228
229 `tt-query` is now `tt-input` - Applied to the typeahead input field.
230
231 Something Missing?
232 ------------------
233
234 If something is missing from this migration guide, pull requests are accepted :)