ember-source 7.3.0-alpha.5 → 7.4.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build-metadata.json +3 -3
- package/dist/dev/packages/@ember/-internals/deprecations/index.js +9 -0
- package/dist/dev/packages/@ember/-internals/glimmer/index.js +7 -7
- package/dist/dev/packages/@ember/-internals/routing/index.js +2 -2
- package/dist/dev/packages/@ember/-internals/runtime/index.js +1 -1
- package/dist/dev/packages/@ember/-internals/runtime/lib/ext/rsvp.js +1 -1
- package/dist/dev/packages/@ember/-internals/runtime/lib/mixins/action_handler.js +4 -0
- package/dist/dev/packages/@ember/-internals/runtime/lib/mixins/target_action_support.js +3 -0
- package/dist/dev/packages/@ember/-internals/views/lib/mixins/action_support.js +2 -0
- package/dist/dev/packages/@ember/application/index.js +3 -3
- package/dist/dev/packages/@ember/application/instance.js +9 -9
- package/dist/dev/packages/@ember/component/helper.js +2 -2
- package/dist/dev/packages/@ember/component/index.js +3 -3
- package/dist/dev/packages/@ember/engine/index.js +3 -3
- package/dist/dev/packages/@ember/engine/instance.js +1 -1
- package/dist/dev/packages/@ember/helper/index.js +1132 -79
- package/dist/dev/packages/@ember/modifier/on.js +1 -1
- package/dist/dev/packages/@ember/object/compat.js +0 -32
- package/dist/dev/packages/@ember/renderer/index.js +1 -1
- package/dist/dev/packages/@ember/routing/-internals.js +2 -2
- package/dist/dev/packages/@ember/routing/index.js +11 -28
- package/dist/dev/packages/@ember/routing/lib/utils.js +2 -2
- package/dist/dev/packages/@ember/routing/route.js +2 -2
- package/dist/dev/packages/@ember/routing/router-service.js +9 -9
- package/dist/dev/packages/@ember/routing/router.js +2 -2
- package/dist/dev/packages/@ember/template-compiler/lib/compile-options.js +3 -3
- package/dist/dev/packages/@ember/template-compiler/lib/template.js +2 -2
- package/dist/dev/packages/@ember/template-factory/index.js +1 -1
- package/dist/dev/packages/@glimmer/opcode-compiler/index.js +2 -2
- package/dist/dev/packages/@glimmer/program/index.js +3 -3
- package/dist/dev/packages/@glimmer/runtime/index.js +7 -7
- package/dist/dev/packages/@glimmer/wire-format/index.js +2 -5
- package/dist/dev/packages/ember/version.js +1 -1
- package/dist/dev/packages/ember-template-compiler/index.js +2 -2
- package/dist/dev/packages/router_js/index.js +2 -2
- package/dist/dev/packages/rsvp/index.js +1 -2281
- package/dist/dev/packages/shared-chunks/{arguments-CDkbOqTS.js → arguments-DniR8eF2.js} +5 -18
- package/dist/dev/packages/shared-chunks/{compiler-QUSl_urU.js → compiler-BHFFl-fv.js} +1 -1
- package/dist/dev/packages/shared-chunks/{curly-BbL6STF2.js → curly-BCD_vyHq.js} +1 -1
- package/dist/dev/packages/shared-chunks/{element-BYLB-q7a.js → element-Cgoi4ldD.js} +0 -24
- package/dist/dev/packages/shared-chunks/get-zsePWrJL.js +40 -0
- package/dist/dev/packages/shared-chunks/hash-BFu91gtE.js +57 -0
- package/dist/dev/packages/shared-chunks/{index-DaFzpTIE.js → index-BYUSIu_W.js} +3 -3
- package/dist/dev/packages/shared-chunks/{index-Czn34wUZ.js → index-Bv9SQpEx.js} +218 -78
- package/dist/dev/packages/shared-chunks/{invoke-d9sqa50M.js → invoke-CgF42joE.js} +1 -1
- package/dist/dev/packages/shared-chunks/{not-DYh6AY9Z.js → not-0cVb-rLf.js} +1 -1
- package/dist/dev/packages/shared-chunks/{on-DlF0Wy7P.js → on-CVIjn2C-.js} +22 -11
- package/dist/dev/packages/shared-chunks/{opcodes-CplRyHl_.js → opcodes-DDajoGhq.js} +0 -4
- package/dist/dev/packages/shared-chunks/{outlet-B4qORyui.js → outlet-BO5-QFmm.js} +3 -3
- package/dist/dev/packages/shared-chunks/{program-context-Dq8xN2HI.js → program-context-BBB1Ga5h.js} +2 -2
- package/dist/dev/packages/shared-chunks/{render-CtH73XOv.js → render-D_Rawf-r.js} +2 -2
- package/dist/{prod/packages/shared-chunks/rsvp.es-DR7yS7qg.js → dev/packages/shared-chunks/rsvp-aLN_pQtn.js} +152 -148
- package/dist/dev/packages/shared-chunks/{setup-registry-h519ZsHS.js → setup-registry-Ci8Af2Bz.js} +35 -13
- package/dist/{prod/packages/shared-chunks/syscall-ops-CN7STuUn.js → dev/packages/shared-chunks/syscall-ops-CkPT1Kfx.js} +1 -2
- package/dist/dev/packages/shared-chunks/{textarea-DEvw4ezm.js → textarea-DvS6Xmdh.js} +3 -23
- package/dist/dev/packages/shared-chunks/{unique-id-DQOhouG1.js → unique-id-Csxuh1I7.js} +0 -4
- package/dist/dev/packages/shared-chunks/{unrecognized-url-error-B8loxkay.js → unrecognized-url-error-cXUp-SK3.js} +1 -1
- package/dist/prod/packages/@ember/-internals/deprecations/index.js +9 -0
- package/dist/prod/packages/@ember/-internals/glimmer/index.js +7 -7
- package/dist/prod/packages/@ember/-internals/routing/index.js +2 -2
- package/dist/prod/packages/@ember/-internals/runtime/index.js +1 -1
- package/dist/prod/packages/@ember/-internals/runtime/lib/ext/rsvp.js +1 -1
- package/dist/prod/packages/@ember/-internals/runtime/lib/mixins/action_handler.js +4 -0
- package/dist/prod/packages/@ember/-internals/runtime/lib/mixins/target_action_support.js +3 -0
- package/dist/prod/packages/@ember/-internals/views/lib/mixins/action_support.js +2 -0
- package/dist/prod/packages/@ember/application/index.js +3 -3
- package/dist/prod/packages/@ember/application/instance.js +9 -9
- package/dist/prod/packages/@ember/component/helper.js +2 -2
- package/dist/prod/packages/@ember/component/index.js +3 -3
- package/dist/prod/packages/@ember/engine/index.js +3 -3
- package/dist/prod/packages/@ember/engine/instance.js +1 -1
- package/dist/prod/packages/@ember/helper/index.js +1132 -79
- package/dist/prod/packages/@ember/modifier/on.js +1 -1
- package/dist/prod/packages/@ember/object/compat.js +0 -32
- package/dist/prod/packages/@ember/renderer/index.js +1 -1
- package/dist/prod/packages/@ember/routing/index.js +10 -27
- package/dist/prod/packages/@ember/routing/lib/utils.js +2 -2
- package/dist/prod/packages/@ember/routing/route.js +2 -2
- package/dist/prod/packages/@ember/routing/router-service.js +9 -9
- package/dist/prod/packages/@ember/routing/router.js +2 -2
- package/dist/prod/packages/@ember/template-compiler/lib/compile-options.js +3 -3
- package/dist/prod/packages/@ember/template-compiler/lib/template.js +2 -2
- package/dist/prod/packages/@ember/template-factory/index.js +1 -1
- package/dist/prod/packages/@glimmer/opcode-compiler/index.js +2 -2
- package/dist/prod/packages/@glimmer/program/index.js +3 -3
- package/dist/prod/packages/@glimmer/runtime/index.js +7 -7
- package/dist/prod/packages/@glimmer/wire-format/index.js +2 -5
- package/dist/prod/packages/ember/version.js +1 -1
- package/dist/prod/packages/ember-template-compiler/index.js +2 -2
- package/dist/prod/packages/router_js/index.js +2 -2
- package/dist/prod/packages/rsvp/index.js +1 -2281
- package/dist/prod/packages/shared-chunks/{arguments-BzAkZVBa.js → arguments-CCYATlEH.js} +1 -18
- package/dist/prod/packages/shared-chunks/{compiler-lBSssiWp.js → compiler-Wt5SWcrF.js} +1 -1
- package/dist/prod/packages/shared-chunks/{curly-CU2jYOtm.js → curly-CdvJuTyW.js} +1 -1
- package/dist/prod/packages/shared-chunks/{element-DgHdPZ8u.js → element-BmBjPjkQ.js} +0 -24
- package/dist/prod/packages/shared-chunks/get-CEjFJzGs.js +40 -0
- package/dist/prod/packages/shared-chunks/hash-BitfXhCx.js +57 -0
- package/dist/prod/packages/shared-chunks/{index-XmtQRWbX.js → index-D8cl-pfl.js} +218 -78
- package/dist/prod/packages/shared-chunks/{index-Bf53M8eS.js → index-kwuZeaNz.js} +3 -3
- package/dist/prod/packages/shared-chunks/{invoke-DhQ5QRp2.js → invoke-4JGJYH7Z.js} +1 -1
- package/dist/prod/packages/shared-chunks/{not-BOIVROuv.js → not-Dn5s9qVZ.js} +1 -1
- package/dist/prod/packages/shared-chunks/{on-BZHAxzdq.js → on-ov4KAucw.js} +22 -11
- package/dist/prod/packages/shared-chunks/{opcodes-CplRyHl_.js → opcodes-DDajoGhq.js} +0 -4
- package/dist/prod/packages/shared-chunks/{outlet-CsNMfeOj.js → outlet-BWnaVOrA.js} +3 -3
- package/dist/prod/packages/shared-chunks/{program-context-COSioH46.js → program-context-WVlzpPdi.js} +2 -2
- package/dist/prod/packages/shared-chunks/{render-Bf7GviCY.js → render-BAVl5E6X.js} +2 -2
- package/dist/{dev/packages/shared-chunks/rsvp.es-DR7yS7qg.js → prod/packages/shared-chunks/rsvp-aLN_pQtn.js} +152 -148
- package/dist/prod/packages/shared-chunks/{setup-registry-DFSQHIUs.js → setup-registry-DeyoFe6Q.js} +35 -13
- package/dist/{dev/packages/shared-chunks/syscall-ops-CN7STuUn.js → prod/packages/shared-chunks/syscall-ops-CkPT1Kfx.js} +1 -2
- package/dist/prod/packages/shared-chunks/{textarea-DMmdvgk2.js → textarea-B-sssXGa.js} +3 -23
- package/dist/prod/packages/shared-chunks/{unique-id-o2pS74go.js → unique-id-BJb1p8EG.js} +0 -4
- package/dist/prod/packages/shared-chunks/{unrecognized-url-error-jjQ-FqKB.js → unrecognized-url-error-xC654tCo.js} +1 -1
- package/docs/data.json +1237 -1395
- package/package.json +52 -47
- package/types/stable/@ember/-internals/deprecations/index.d.ts +6 -0
- package/types/stable/@ember/-internals/glimmer/index.d.ts +7 -380
- package/types/stable/@ember/-internals/glimmer/lib/component.d.ts +1 -1
- package/types/stable/@ember/-internals/glimmer/lib/helper.d.ts +2 -2
- package/types/stable/@ember/-internals/glimmer/lib/helpers/each-in.d.ts +196 -63
- package/types/stable/@ember/-internals/glimmer/lib/helpers/element.d.ts +0 -24
- package/types/stable/@ember/-internals/glimmer/lib/helpers/mut.d.ts +3 -2
- package/types/stable/@ember/-internals/glimmer/lib/helpers/readonly.d.ts +3 -1
- package/types/stable/@ember/-internals/glimmer/lib/helpers/unbound.d.ts +6 -2
- package/types/stable/@ember/-internals/glimmer/lib/helpers/unique-id.d.ts +0 -3
- package/types/stable/@ember/-internals/glimmer/lib/syntax/mount.d.ts +4 -2
- package/types/stable/@ember/-internals/glimmer/lib/syntax/outlet.d.ts +7 -2
- package/types/stable/@ember/helper/index.d.ts +1113 -73
- package/types/stable/@ember/object/compat.d.ts +0 -32
- package/types/stable/@ember/object/core.d.ts +1 -1
- package/types/stable/@ember/routing/router-service.d.ts +9 -9
- package/types/stable/@glimmer/interfaces/lib/compile/wire-format/api.d.ts +1 -9
- package/types/stable/@glimmer/interfaces/lib/compile/wire-format/opcodes.d.ts +0 -4
- package/types/stable/@glimmer/interfaces/lib/vm-opcodes.d.ts +0 -4
- package/types/stable/@glimmer/opcode-compiler/lib/opcode-builder/helpers/conditional.d.ts +1 -1
- package/types/stable/@glimmer/opcode-compiler/lib/syntax/statements.d.ts +1 -1
- package/types/stable/@glimmer/runtime/lib/helpers/array.d.ts +0 -33
- package/types/stable/@glimmer/runtime/lib/helpers/concat.d.ts +0 -25
- package/types/stable/@glimmer/runtime/lib/helpers/fn.d.ts +0 -70
- package/types/stable/@glimmer/runtime/lib/helpers/get.d.ts +0 -69
- package/types/stable/@glimmer/runtime/lib/helpers/hash.d.ts +0 -36
- package/types/stable/index.d.ts +0 -14
- package/dist/dev/packages/shared-chunks/get-6I3sjd-I.js +0 -135
- package/dist/dev/packages/shared-chunks/hash-6NDs_5_f.js +0 -198
- package/dist/prod/packages/shared-chunks/get-Dago5uGl.js +0 -135
- package/dist/prod/packages/shared-chunks/hash-gEXIsSO4.js +0 -198
- package/types/stable/@ember/-internals/glimmer/lib/helpers/array.d.ts +0 -43
- package/types/stable/@ember/-internals/glimmer/lib/helpers/component.d.ts +0 -93
- package/types/stable/@ember/-internals/glimmer/lib/helpers/concat.d.ts +0 -32
- package/types/stable/@ember/-internals/glimmer/lib/helpers/fn.d.ts +0 -77
- package/types/stable/@ember/-internals/glimmer/lib/helpers/get.d.ts +0 -94
- package/types/stable/@ember/-internals/glimmer/lib/helpers/hash.d.ts +0 -46
- package/types/stable/@ember/-internals/glimmer/lib/helpers/helper.d.ts +0 -43
- package/types/stable/@ember/-internals/glimmer/lib/helpers/if-unless.d.ts +0 -228
- package/types/stable/@ember/-internals/glimmer/lib/helpers/log.d.ts +0 -19
- package/types/stable/@ember/-internals/glimmer/lib/helpers/modifier.d.ts +0 -42
- package/types/stable/@ember/-internals/glimmer/lib/helpers/page-title.d.ts +0 -24
- package/types/stable/@ember/-internals/glimmer/lib/modifiers/on.d.ts +0 -95
- package/types/stable/@ember/-internals/glimmer/lib/syntax/in-element.d.ts +0 -49
- package/types/stable/@ember/-internals/glimmer/lib/syntax/let.d.ts +0 -43
|
@@ -52,11 +52,12 @@ declare module '@ember/helper' {
|
|
|
52
52
|
capability is enabled.
|
|
53
53
|
|
|
54
54
|
@method capabilities
|
|
55
|
-
@for @ember/helper
|
|
56
55
|
@static
|
|
56
|
+
@for @ember/helper
|
|
57
57
|
@param {String} managerApiVersion The version of capabilities that are being used
|
|
58
58
|
@param options The capabilities values
|
|
59
59
|
@return {Capabilities} The capabilities object instance
|
|
60
|
+
@since 3.23.0
|
|
60
61
|
@public
|
|
61
62
|
*/
|
|
62
63
|
export const capabilities: typeof helperCapabilities;
|
|
@@ -250,6 +251,7 @@ declare module '@ember/helper' {
|
|
|
250
251
|
@param {Function} factory A factory function which receives an optional owner, and returns a helper manager
|
|
251
252
|
@param {object} definition The definition to associate the manager factory with
|
|
252
253
|
@return {object} The definition passed into setHelperManager
|
|
254
|
+
@since 3.23.0
|
|
253
255
|
@public
|
|
254
256
|
*/
|
|
255
257
|
export const setHelperManager: typeof glimmerSetHelperManager;
|
|
@@ -260,8 +262,7 @@ declare module '@ember/helper' {
|
|
|
260
262
|
To access a helper's value you have to use `getValue` from
|
|
261
263
|
`@glimmer/tracking/primitives/cache`.
|
|
262
264
|
|
|
263
|
-
```js
|
|
264
|
-
// app/components/data-loader.js
|
|
265
|
+
```gjs {data-filename="app/components/data-loader.js"}
|
|
265
266
|
import Component from '@glimmer/component';
|
|
266
267
|
import { getValue } from '@glimmer/tracking/primitives/cache';
|
|
267
268
|
import Helper from '@ember/component/helper';
|
|
@@ -284,9 +285,10 @@ declare module '@ember/helper' {
|
|
|
284
285
|
return getValue(this.plusOne);
|
|
285
286
|
}
|
|
286
287
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
288
|
+
|
|
289
|
+
<template>
|
|
290
|
+
{{this.value}}
|
|
291
|
+
</template>
|
|
290
292
|
```
|
|
291
293
|
|
|
292
294
|
It receives three arguments:
|
|
@@ -314,6 +316,7 @@ declare module '@ember/helper' {
|
|
|
314
316
|
@param {object} definition The helper definition
|
|
315
317
|
@param {Function} computeArgs An optional function that produces args
|
|
316
318
|
@returns
|
|
319
|
+
@since 3.23.0
|
|
317
320
|
@public
|
|
318
321
|
*/
|
|
319
322
|
export const invokeHelper: typeof glimmerInvokeHelper;
|
|
@@ -321,13 +324,35 @@ declare module '@ember/helper' {
|
|
|
321
324
|
* Using the `{{hash}}` helper, you can pass objects directly from the template
|
|
322
325
|
* as an argument to your components.
|
|
323
326
|
*
|
|
324
|
-
* ```
|
|
327
|
+
* ```gjs
|
|
325
328
|
* <template>
|
|
326
329
|
* {{#each-in (hash givenName='Jen' familyName='Weber') as |key value|}}
|
|
327
330
|
* <p>{{key}}: {{value}}</p>
|
|
328
331
|
* {{/each-in}}
|
|
329
332
|
* </template>
|
|
330
333
|
* ```
|
|
334
|
+
*
|
|
335
|
+
*
|
|
336
|
+
* Note that the hash is an empty object with no prototype chain, therefore
|
|
337
|
+
* common methods like `toString` are not available in the resulting hash.
|
|
338
|
+
* If you need to use such a method, you can use the `call` or `apply`
|
|
339
|
+
* approach:
|
|
340
|
+
*
|
|
341
|
+
* ```js
|
|
342
|
+
* function toString(obj) {
|
|
343
|
+
* return Object.prototype.toString.apply(obj);
|
|
344
|
+
* }
|
|
345
|
+
* ```
|
|
346
|
+
* The `hash` helper is available as a keyword and does not need to be imported.
|
|
347
|
+
*
|
|
348
|
+
* @method hash
|
|
349
|
+
* @public
|
|
350
|
+
* @static
|
|
351
|
+
* @for Keywords
|
|
352
|
+
* @noimport
|
|
353
|
+
* @param {Object} options
|
|
354
|
+
* @return {Object} Hash
|
|
355
|
+
* @since 2.3.0
|
|
331
356
|
*/
|
|
332
357
|
export const hash: HashHelper;
|
|
333
358
|
export interface HashHelper extends Opaque<"helper:hash"> {
|
|
@@ -336,8 +361,7 @@ declare module '@ember/helper' {
|
|
|
336
361
|
* Using the `{{array}}` helper, you can pass arrays directly from the template
|
|
337
362
|
* as an argument to your components.
|
|
338
363
|
*
|
|
339
|
-
* ```
|
|
340
|
-
*
|
|
364
|
+
* ```gjs
|
|
341
365
|
* <template>
|
|
342
366
|
* <ul>
|
|
343
367
|
* {{#each (array 'Tom Dale' 'Yehuda Katz' @anotherPerson) as |person|}}
|
|
@@ -346,27 +370,48 @@ declare module '@ember/helper' {
|
|
|
346
370
|
* </ul>
|
|
347
371
|
* </template>
|
|
348
372
|
* ```
|
|
373
|
+
*
|
|
374
|
+
* The `array` helper is available as a keyword and does not need to be imported.
|
|
375
|
+
*
|
|
376
|
+
* @method array
|
|
377
|
+
* @public
|
|
378
|
+
* @static
|
|
379
|
+
* @for Keywords
|
|
380
|
+
* @noimport
|
|
381
|
+
* @param {Array} options
|
|
382
|
+
* @return {Array} Array
|
|
383
|
+
* @since 3.8.0
|
|
349
384
|
*/
|
|
350
385
|
export const array: ArrayHelper;
|
|
351
386
|
export interface ArrayHelper extends Opaque<"helper:array"> {
|
|
352
387
|
}
|
|
353
388
|
/**
|
|
354
|
-
* The `{{concat}}` helper
|
|
355
|
-
* parameters to a component or helper as a single parameter in the format of a
|
|
356
|
-
* concatenated string.
|
|
357
|
-
*
|
|
358
|
-
* For example:
|
|
389
|
+
* The `{{concat}}` helper Concatenates the given arguments into a string.
|
|
359
390
|
*
|
|
360
|
-
*
|
|
361
|
-
* import { concat } from '@ember/helper';
|
|
391
|
+
* Example:
|
|
362
392
|
*
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
393
|
+
```gjs
|
|
394
|
+
import { concat } from '@ember/helper';
|
|
395
|
+
|
|
396
|
+
<template>
|
|
397
|
+
{{yield (concat firstName " " lastName)}}
|
|
398
|
+
|
|
399
|
+
{{! would yield name="<first name value> <last name value>" to the component}}
|
|
400
|
+
</template>
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
or for angle bracket invocation, you actually don't need concat at all:
|
|
404
|
+
|
|
405
|
+
```handlebars
|
|
406
|
+
<SomeComponent @name="{{firstName}} {{lastName}}" />
|
|
407
|
+
```
|
|
367
408
|
*
|
|
368
|
-
*
|
|
369
|
-
*
|
|
409
|
+
* @method concat
|
|
410
|
+
* @for @ember/helper
|
|
411
|
+
* @exampleimport import { concat } from '@ember/helper';
|
|
412
|
+
* @public
|
|
413
|
+
* @static
|
|
414
|
+
* @since 1.13.0
|
|
370
415
|
*/
|
|
371
416
|
export const concat: ConcatHelper;
|
|
372
417
|
export interface ConcatHelper extends Opaque<"helper:concat"> {
|
|
@@ -378,7 +423,7 @@ declare module '@ember/helper' {
|
|
|
378
423
|
*
|
|
379
424
|
* To access a property on an object with a string key:
|
|
380
425
|
*
|
|
381
|
-
* ```
|
|
426
|
+
* ```gjs
|
|
382
427
|
* import { get } from '@ember/helper';
|
|
383
428
|
*
|
|
384
429
|
* <template>
|
|
@@ -388,7 +433,7 @@ declare module '@ember/helper' {
|
|
|
388
433
|
*
|
|
389
434
|
* To access the first element in an array:
|
|
390
435
|
*
|
|
391
|
-
* ```
|
|
436
|
+
* ```gjs
|
|
392
437
|
* import { get } from '@ember/helper';
|
|
393
438
|
*
|
|
394
439
|
* <template>
|
|
@@ -398,7 +443,7 @@ declare module '@ember/helper' {
|
|
|
398
443
|
*
|
|
399
444
|
* To access a property on an object with a dynamic key:
|
|
400
445
|
*
|
|
401
|
-
* ```
|
|
446
|
+
* ```gjs
|
|
402
447
|
* import { get } from '@ember/helper';
|
|
403
448
|
*
|
|
404
449
|
* <template>
|
|
@@ -408,6 +453,13 @@ declare module '@ember/helper' {
|
|
|
408
453
|
*
|
|
409
454
|
* This will display the result of `@foo.item1` when `index` is `1`, and
|
|
410
455
|
* `this.foo.item2` when `index` is `2`, etc.
|
|
456
|
+
*
|
|
457
|
+
* @method get
|
|
458
|
+
* @for @ember/helper
|
|
459
|
+
* @since 2.1.0
|
|
460
|
+
* @exampleimport import { get } from '@ember/helper';
|
|
461
|
+
* @public
|
|
462
|
+
* @static
|
|
411
463
|
*/
|
|
412
464
|
export const get: GetHelper;
|
|
413
465
|
export interface GetHelper extends Opaque<"helper:get"> {
|
|
@@ -417,9 +469,7 @@ declare module '@ember/helper' {
|
|
|
417
469
|
* a new function that combines. This allows you to pass parameters along to
|
|
418
470
|
* functions in your templates:
|
|
419
471
|
*
|
|
420
|
-
* ```
|
|
421
|
-
* import { fn } from '@ember/helper';
|
|
422
|
-
*
|
|
472
|
+
* ```gjs
|
|
423
473
|
* function showAlert(message) {
|
|
424
474
|
* alert(`The message is: '${message}'`);
|
|
425
475
|
* }
|
|
@@ -430,6 +480,55 @@ declare module '@ember/helper' {
|
|
|
430
480
|
* </button>
|
|
431
481
|
* </template>
|
|
432
482
|
* ```
|
|
483
|
+
*
|
|
484
|
+
* For example, if you have an `each` helper looping over a number of items, you
|
|
485
|
+
* may need to pass a function that expects to receive the item as an argument
|
|
486
|
+
* to a component invoked within the loop. Here's how you could use the `fn`
|
|
487
|
+
* helper to pass both the function and its arguments together:
|
|
488
|
+
*
|
|
489
|
+
* ```gjs {data-filename="app/components/items-listing.gjs"}
|
|
490
|
+
* <template>
|
|
491
|
+
* {{#each @items as |item|}}
|
|
492
|
+
* <DisplayItem @item=item @select={{fn this.handleSelected item}} />
|
|
493
|
+
* {{/each}}
|
|
494
|
+
* </template>
|
|
495
|
+
* ```
|
|
496
|
+
*
|
|
497
|
+
* ```gjs {data-filename="app/components/items-list.gjs"}
|
|
498
|
+
* import Component from '@glimmer/component';
|
|
499
|
+
* import { action } from '@ember/object';
|
|
500
|
+
*
|
|
501
|
+
* export default class ItemsList extends Component {
|
|
502
|
+
* @action
|
|
503
|
+
* handleSelected(item) {
|
|
504
|
+
* // ...snip...
|
|
505
|
+
* }
|
|
506
|
+
* }
|
|
507
|
+
* ```
|
|
508
|
+
*
|
|
509
|
+
* In this case the `DisplayItem` component will receive a normal function
|
|
510
|
+
* that it can invoke. When it invokes the function, the `handleSelected`
|
|
511
|
+
* function will receive the `item` and any arguments passed, thanks to the
|
|
512
|
+
* `fn` helper.
|
|
513
|
+
*
|
|
514
|
+
* Let's take a look at what that means in a couple circumstances:
|
|
515
|
+
*
|
|
516
|
+
* - When invoked as `this.args.select()` the `handleSelected` function will
|
|
517
|
+
* receive the `item` from the loop as its first and only argument.
|
|
518
|
+
* - When invoked as `this.args.select('foo')` the `handleSelected` function
|
|
519
|
+
* will receive the `item` from the loop as its first argument and the
|
|
520
|
+
* string `'foo'` as its second argument.
|
|
521
|
+
*
|
|
522
|
+
* See also [partial application](https://en.wikipedia.org/wiki/Partial_application).
|
|
523
|
+
*
|
|
524
|
+
* The `fn` helper is available as a keyword and does not need to be imported.
|
|
525
|
+
*
|
|
526
|
+
* @method fn
|
|
527
|
+
* @for Keywords
|
|
528
|
+
* @noimport
|
|
529
|
+
* @public
|
|
530
|
+
* @since 3.11.0
|
|
531
|
+
* @static
|
|
433
532
|
*/
|
|
434
533
|
export const fn: FnHelper;
|
|
435
534
|
export interface FnHelper extends Opaque<"helper:fn"> {
|
|
@@ -438,21 +537,23 @@ declare module '@ember/helper' {
|
|
|
438
537
|
* The `{{gt}}` helper returns `true` if the first argument is greater than
|
|
439
538
|
* the second argument.
|
|
440
539
|
*
|
|
441
|
-
* ```
|
|
442
|
-
* import { gt } from '@ember/helper';
|
|
443
|
-
*
|
|
540
|
+
* ```gjs
|
|
444
541
|
* <template>
|
|
445
542
|
* {{if (gt @score 100) "High score!" "Keep trying"}}
|
|
446
543
|
* </template>
|
|
447
544
|
* ```
|
|
448
545
|
*
|
|
449
|
-
*
|
|
450
|
-
* does not need to be imported.
|
|
546
|
+
* The `gt` helper is available as a keyword and does not need to be imported.
|
|
451
547
|
*
|
|
452
548
|
* @method gt
|
|
453
549
|
* @param {number} left
|
|
454
550
|
* @param {number} right
|
|
455
551
|
* @return {boolean}
|
|
552
|
+
* @noimport
|
|
553
|
+
* @for Keywords
|
|
554
|
+
* @since 7.1.0
|
|
555
|
+
* @static
|
|
556
|
+
* @public
|
|
456
557
|
*/
|
|
457
558
|
export const gt: GtHelper;
|
|
458
559
|
export interface GtHelper extends Opaque<"helper:gt"> {
|
|
@@ -461,21 +562,23 @@ declare module '@ember/helper' {
|
|
|
461
562
|
* The `{{gte}}` helper returns `true` if the first argument is greater than
|
|
462
563
|
* or equal to the second argument.
|
|
463
564
|
*
|
|
464
|
-
* ```
|
|
465
|
-
* import { gte } from '@ember/helper';
|
|
466
|
-
*
|
|
565
|
+
* ```gjs
|
|
467
566
|
* <template>
|
|
468
567
|
* {{if (gte @age 18) "Adult" "Minor"}}
|
|
469
568
|
* </template>
|
|
470
569
|
* ```
|
|
471
570
|
*
|
|
472
|
-
*
|
|
473
|
-
* does not need to be imported.
|
|
571
|
+
* The `gte` helper is available as a keyword and does not need to be imported.
|
|
474
572
|
*
|
|
475
573
|
* @method gte
|
|
476
574
|
* @param {number} left
|
|
477
575
|
* @param {number} right
|
|
478
576
|
* @return {boolean}
|
|
577
|
+
* @noimport
|
|
578
|
+
* @for Keywords
|
|
579
|
+
* @since 7.1.0
|
|
580
|
+
* @static
|
|
581
|
+
* @public
|
|
479
582
|
*/
|
|
480
583
|
export const gte: GteHelper;
|
|
481
584
|
export interface GteHelper extends Opaque<"helper:gte"> {
|
|
@@ -484,21 +587,23 @@ declare module '@ember/helper' {
|
|
|
484
587
|
* The `{{lt}}` helper returns `true` if the first argument is less than
|
|
485
588
|
* the second argument.
|
|
486
589
|
*
|
|
487
|
-
* ```
|
|
488
|
-
* import { lt } from '@ember/helper';
|
|
489
|
-
*
|
|
590
|
+
* ```gjs
|
|
490
591
|
* <template>
|
|
491
592
|
* {{if (lt @temperature 0) "Freezing" "Above zero"}}
|
|
492
593
|
* </template>
|
|
493
594
|
* ```
|
|
494
595
|
*
|
|
495
|
-
*
|
|
496
|
-
* does not need to be imported.
|
|
596
|
+
* The `lt` helper is available as a keyword and does not need to be imported.
|
|
497
597
|
*
|
|
498
598
|
* @method lt
|
|
499
599
|
* @param {number} left
|
|
500
600
|
* @param {number} right
|
|
501
601
|
* @return {boolean}
|
|
602
|
+
* @noimport
|
|
603
|
+
* @for Keywords
|
|
604
|
+
* @since 7.1.0
|
|
605
|
+
* @static
|
|
606
|
+
* @public
|
|
502
607
|
*/
|
|
503
608
|
export const lt: LtHelper;
|
|
504
609
|
export interface LtHelper extends Opaque<"helper:lt"> {
|
|
@@ -507,21 +612,23 @@ declare module '@ember/helper' {
|
|
|
507
612
|
* The `{{lte}}` helper returns `true` if the first argument is less than
|
|
508
613
|
* or equal to the second argument.
|
|
509
614
|
*
|
|
510
|
-
* ```
|
|
511
|
-
* import { lte } from '@ember/helper';
|
|
512
|
-
*
|
|
615
|
+
* ```gjs
|
|
513
616
|
* <template>
|
|
514
617
|
* {{if (lte @count 0) "Empty" "Has items"}}
|
|
515
618
|
* </template>
|
|
516
619
|
* ```
|
|
517
620
|
*
|
|
518
|
-
*
|
|
519
|
-
* does not need to be imported.
|
|
621
|
+
* The `lte` helper is available as a keyword and does not need to be imported.
|
|
520
622
|
*
|
|
521
623
|
* @method lte
|
|
522
624
|
* @param {number} left
|
|
523
625
|
* @param {number} right
|
|
524
626
|
* @return {boolean}
|
|
627
|
+
* @noimport
|
|
628
|
+
* @for Keywords
|
|
629
|
+
* @since 7.1.0
|
|
630
|
+
* @static
|
|
631
|
+
* @public
|
|
525
632
|
*/
|
|
526
633
|
export const lte: LteHelper;
|
|
527
634
|
export interface LteHelper extends Opaque<"helper:lte"> {
|
|
@@ -529,9 +636,7 @@ declare module '@ember/helper' {
|
|
|
529
636
|
/**
|
|
530
637
|
* The `element` helper lets you dynamically set the tag name of an element.
|
|
531
638
|
*
|
|
532
|
-
* ```
|
|
533
|
-
* import { element } from '@ember/helper';
|
|
534
|
-
*
|
|
639
|
+
* ```gjs
|
|
535
640
|
* <template>
|
|
536
641
|
* {{#let (element @tagName) as |Tag|}}
|
|
537
642
|
* <Tag class="my-element">Hello</Tag>
|
|
@@ -543,8 +648,15 @@ declare module '@ember/helper' {
|
|
|
543
648
|
* When `@tagName` is an empty string, the block content is rendered without a
|
|
544
649
|
* wrapping element. When `@tagName` is `null` or `undefined`, nothing is rendered.
|
|
545
650
|
*
|
|
651
|
+
* The `element` helper is available as a keyword and does not need to be imported.
|
|
652
|
+
*
|
|
546
653
|
* @method element
|
|
547
654
|
* @param {string} tagName
|
|
655
|
+
* @noimport
|
|
656
|
+
* @for Keywords
|
|
657
|
+
* @since 7.1.0
|
|
658
|
+
* @static
|
|
659
|
+
* @public
|
|
548
660
|
*/
|
|
549
661
|
export const element: ElementHelper;
|
|
550
662
|
export interface ElementHelper extends Opaque<"helper:element"> {
|
|
@@ -556,7 +668,7 @@ declare module '@ember/helper' {
|
|
|
556
668
|
* Each invocation of {{uniqueId}} will return a new, unique ID string.
|
|
557
669
|
* You can use the `let` helper to create an ID that can be reused within a template.
|
|
558
670
|
*
|
|
559
|
-
* ```
|
|
671
|
+
* ```gjs
|
|
560
672
|
* import { uniqueId } from '@ember/helper';
|
|
561
673
|
*
|
|
562
674
|
* <template>
|
|
@@ -566,6 +678,13 @@ declare module '@ember/helper' {
|
|
|
566
678
|
* {{/let}}
|
|
567
679
|
* </template>
|
|
568
680
|
* ```
|
|
681
|
+
*
|
|
682
|
+
* @method uniqueId
|
|
683
|
+
* @for @ember/helper
|
|
684
|
+
* @public
|
|
685
|
+
* @static
|
|
686
|
+
* @exampleimport import { uniqueId } from '@ember/helper';
|
|
687
|
+
* @since 4.4.0
|
|
569
688
|
*/
|
|
570
689
|
export const uniqueId: typeof glimmerUniqueId;
|
|
571
690
|
export type UniqueIdHelper = typeof uniqueId;
|
|
@@ -573,21 +692,23 @@ declare module '@ember/helper' {
|
|
|
573
692
|
* The `{{eq}}` helper returns `true` if its two arguments are strictly equal
|
|
574
693
|
* (`===`). Takes exactly two arguments.
|
|
575
694
|
*
|
|
576
|
-
* ```
|
|
577
|
-
* import { eq } from '@ember/helper';
|
|
578
|
-
*
|
|
695
|
+
* ```gjs
|
|
579
696
|
* <template>
|
|
580
697
|
* {{if (eq @status "active") "Active" "Inactive"}}
|
|
581
698
|
* </template>
|
|
582
699
|
* ```
|
|
583
700
|
*
|
|
584
|
-
*
|
|
585
|
-
* does not need to be imported.
|
|
701
|
+
* The `eq` helper is available as a keyword and does not need to be imported.
|
|
586
702
|
*
|
|
587
703
|
* @method eq
|
|
588
704
|
* @param {unknown} left
|
|
589
705
|
* @param {unknown} right
|
|
590
706
|
* @return {boolean}
|
|
707
|
+
* @noimport
|
|
708
|
+
* @for Keywords
|
|
709
|
+
* @static
|
|
710
|
+
* @since 7.1.0
|
|
711
|
+
* @public
|
|
591
712
|
*/
|
|
592
713
|
export const eq: EqHelper;
|
|
593
714
|
export interface EqHelper extends Opaque<"helper:eq"> {
|
|
@@ -596,21 +717,23 @@ declare module '@ember/helper' {
|
|
|
596
717
|
* The `{{neq}}` helper returns `true` if its two arguments are strictly
|
|
597
718
|
* not equal (`!==`). Takes exactly two arguments.
|
|
598
719
|
*
|
|
599
|
-
* ```
|
|
600
|
-
* import { neq } from '@ember/helper';
|
|
601
|
-
*
|
|
720
|
+
* ```gjs
|
|
602
721
|
* <template>
|
|
603
722
|
* {{if (neq @status "active") "Not active" "Active"}}
|
|
604
723
|
* </template>
|
|
605
724
|
* ```
|
|
606
725
|
*
|
|
607
|
-
*
|
|
608
|
-
* does not need to be imported.
|
|
726
|
+
* The `neq` helper is available as a keyword and does not need to be imported.
|
|
609
727
|
*
|
|
610
728
|
* @method neq
|
|
611
729
|
* @param {unknown} left
|
|
612
730
|
* @param {unknown} right
|
|
613
731
|
* @return {boolean}
|
|
732
|
+
* @for Keywords
|
|
733
|
+
* @noimport
|
|
734
|
+
* @static
|
|
735
|
+
* @since 7.1.0
|
|
736
|
+
* @public
|
|
614
737
|
*/
|
|
615
738
|
export const neq: NeqHelper;
|
|
616
739
|
export interface NeqHelper extends Opaque<"helper:neq"> {
|
|
@@ -620,20 +743,22 @@ declare module '@ember/helper' {
|
|
|
620
743
|
* falsy value (using Handlebars truthiness) or the right-most value if all
|
|
621
744
|
* are truthy. Requires at least two arguments.
|
|
622
745
|
*
|
|
623
|
-
* ```
|
|
624
|
-
* import { and } from '@ember/helper';
|
|
625
|
-
*
|
|
746
|
+
* ```gjs
|
|
626
747
|
* <template>
|
|
627
748
|
* {{if (and @isAdmin @isLoggedIn) "Welcome, admin!" "Access denied"}}
|
|
628
749
|
* </template>
|
|
629
750
|
* ```
|
|
630
751
|
*
|
|
631
|
-
*
|
|
632
|
-
* does not need to be imported.
|
|
752
|
+
* The `and` helper is available as a keyword and does not need to be imported.
|
|
633
753
|
*
|
|
634
754
|
* @method and
|
|
635
755
|
* @param {unknown} args Two or more values to evaluate
|
|
636
756
|
* @return {unknown} The first falsy value or the last value
|
|
757
|
+
* @noimport
|
|
758
|
+
* @for Keywords
|
|
759
|
+
* @static
|
|
760
|
+
* @since 7.1.0
|
|
761
|
+
* @public
|
|
637
762
|
*/
|
|
638
763
|
export const and: AndHelper;
|
|
639
764
|
export interface AndHelper extends Opaque<"helper:and"> {
|
|
@@ -643,9 +768,7 @@ declare module '@ember/helper' {
|
|
|
643
768
|
* truthy value (using Handlebars truthiness) or the right-most value if all
|
|
644
769
|
* are falsy. Requires at least two arguments.
|
|
645
770
|
*
|
|
646
|
-
* ```
|
|
647
|
-
* import { or } from '@ember/helper';
|
|
648
|
-
*
|
|
771
|
+
* ```gjs
|
|
649
772
|
* <template>
|
|
650
773
|
* {{if (or @hasAccess @isAdmin) "Welcome!" "No access"}}
|
|
651
774
|
* </template>
|
|
@@ -657,6 +780,11 @@ declare module '@ember/helper' {
|
|
|
657
780
|
* @method or
|
|
658
781
|
* @param {unknown} args Two or more values to evaluate
|
|
659
782
|
* @return {unknown} The first truthy value or the last value
|
|
783
|
+
* @noimport
|
|
784
|
+
* @for Keywords
|
|
785
|
+
* @static
|
|
786
|
+
* @since 7.1.0
|
|
787
|
+
* @public
|
|
660
788
|
*/
|
|
661
789
|
export const or: OrHelper;
|
|
662
790
|
export interface OrHelper extends Opaque<"helper:or"> {
|
|
@@ -665,9 +793,7 @@ declare module '@ember/helper' {
|
|
|
665
793
|
* The `{{not}}` helper returns the logical negation of its argument using
|
|
666
794
|
* Handlebars truthiness. Takes exactly one argument.
|
|
667
795
|
*
|
|
668
|
-
* ```
|
|
669
|
-
* import { not } from '@ember/helper';
|
|
670
|
-
*
|
|
796
|
+
* ```gjs
|
|
671
797
|
* <template>
|
|
672
798
|
* {{if (not @isDisabled) "Enabled" "Disabled"}}
|
|
673
799
|
* </template>
|
|
@@ -679,8 +805,922 @@ declare module '@ember/helper' {
|
|
|
679
805
|
* @method not
|
|
680
806
|
* @param {unknown} value The value to negate
|
|
681
807
|
* @return {boolean}
|
|
808
|
+
* @for Keywords
|
|
809
|
+
* @noimport
|
|
810
|
+
* @static
|
|
811
|
+
* @since 7.1.0
|
|
812
|
+
* @public
|
|
682
813
|
*/
|
|
683
814
|
export const not: NotHelper;
|
|
684
815
|
export interface NotHelper extends Opaque<"helper:not"> {
|
|
685
816
|
}
|
|
817
|
+
/**
|
|
818
|
+
`{{yield}}` denotes an area of a template that will be rendered inside
|
|
819
|
+
of another template.
|
|
820
|
+
|
|
821
|
+
### Use with `Component`
|
|
822
|
+
|
|
823
|
+
When designing components, `{{yield}}` is used to denote where, inside the component's
|
|
824
|
+
template, an optional block passed to the component should render:
|
|
825
|
+
|
|
826
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
827
|
+
import LabeledTextField from '../components/labeled-textfield';
|
|
828
|
+
|
|
829
|
+
<template>
|
|
830
|
+
<LabeledTextField @value={{@model.name}}>
|
|
831
|
+
First name:
|
|
832
|
+
</LabeledTextField>
|
|
833
|
+
</template>
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
```gjs {data-filename="app/components/labeled-textfield.gjs"}
|
|
837
|
+
import { Input } from '@ember/component';
|
|
838
|
+
|
|
839
|
+
<template>
|
|
840
|
+
<label>
|
|
841
|
+
{{yield}} <Input @value={{@value}} />
|
|
842
|
+
</label>
|
|
843
|
+
</template>
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
Result:
|
|
847
|
+
|
|
848
|
+
```html
|
|
849
|
+
<label>
|
|
850
|
+
First name: <input type="text" />
|
|
851
|
+
</label>
|
|
852
|
+
```
|
|
853
|
+
|
|
854
|
+
Additionally, you can `yield` properties into the context for use by the consumer:
|
|
855
|
+
|
|
856
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
857
|
+
import Component from '@glimmer/component';
|
|
858
|
+
import LabeledTextField from '../components/labeled-textfield';
|
|
859
|
+
|
|
860
|
+
export default class Application extends Component {
|
|
861
|
+
firstNameValidator = (value) => {
|
|
862
|
+
// validates
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
<template>
|
|
866
|
+
<LabeledTextField @value={{@model.validation}} @validator={{this.firstNameValidator}} as |validationError|>
|
|
867
|
+
{{#if validationError}}
|
|
868
|
+
<p class="error">{{validationError}}</p>
|
|
869
|
+
{{/if}}
|
|
870
|
+
First name:
|
|
871
|
+
</LabeledTextField>
|
|
872
|
+
</template>
|
|
873
|
+
}
|
|
874
|
+
```
|
|
875
|
+
|
|
876
|
+
```gjs {data-filename="app/components/labeled-textfield.gjs"}
|
|
877
|
+
import { Input } from '@ember/component';
|
|
878
|
+
|
|
879
|
+
<template>
|
|
880
|
+
<label>
|
|
881
|
+
{{yield this.validationError}} <Input @value={{@value}} />
|
|
882
|
+
</label>
|
|
883
|
+
</template>
|
|
884
|
+
```
|
|
885
|
+
|
|
886
|
+
Result:
|
|
887
|
+
|
|
888
|
+
```html
|
|
889
|
+
<label>
|
|
890
|
+
<p class="error">First Name must be at least 3 characters long.</p>
|
|
891
|
+
First name: <input type="text" />
|
|
892
|
+
</label>
|
|
893
|
+
```
|
|
894
|
+
|
|
895
|
+
`yield` can also be used with the `hash` helper:
|
|
896
|
+
|
|
897
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
898
|
+
import DateRanges from '../components/date-ranges';
|
|
899
|
+
|
|
900
|
+
<template>
|
|
901
|
+
<DateRanges @value={{@model.date}} as |range|>
|
|
902
|
+
Start date: {{range.start}}
|
|
903
|
+
End date: {{range.end}}
|
|
904
|
+
</DateRanges>
|
|
905
|
+
</template>
|
|
906
|
+
```
|
|
907
|
+
|
|
908
|
+
```gjs {data-filename="app/components/date-ranges.gjs"}
|
|
909
|
+
<template>
|
|
910
|
+
<div>
|
|
911
|
+
{{yield (hash start=@value.start end=@value.end)}}
|
|
912
|
+
</div>
|
|
913
|
+
</template>
|
|
914
|
+
```
|
|
915
|
+
|
|
916
|
+
Result:
|
|
917
|
+
|
|
918
|
+
```html
|
|
919
|
+
<div>
|
|
920
|
+
Start date: July 1st
|
|
921
|
+
End date: July 30th
|
|
922
|
+
</div>
|
|
923
|
+
```
|
|
924
|
+
|
|
925
|
+
Multiple values can be yielded as block params:
|
|
926
|
+
|
|
927
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
928
|
+
import Banner from '../components/banner';
|
|
929
|
+
|
|
930
|
+
<template>
|
|
931
|
+
<Banner @value={{@model}} as |title subtitle body|>
|
|
932
|
+
<h1>{{title}}</h1>
|
|
933
|
+
<h2>{{subtitle}}</h2>
|
|
934
|
+
{{body}}
|
|
935
|
+
</Banner>
|
|
936
|
+
</template>
|
|
937
|
+
```
|
|
938
|
+
|
|
939
|
+
```gjs {data-filename="app/components/banner.gjs"}
|
|
940
|
+
<template>
|
|
941
|
+
<div>
|
|
942
|
+
{{yield "Hello title" "hello subtitle" "body text"}}
|
|
943
|
+
</div>
|
|
944
|
+
</template>
|
|
945
|
+
```
|
|
946
|
+
|
|
947
|
+
Result:
|
|
948
|
+
|
|
949
|
+
```html
|
|
950
|
+
<div>
|
|
951
|
+
<h1>Hello title</h1>
|
|
952
|
+
<h2>hello subtitle</h2>
|
|
953
|
+
body text
|
|
954
|
+
</div>
|
|
955
|
+
```
|
|
956
|
+
|
|
957
|
+
However, it is preferred to use the hash helper, as this can prevent breaking changes to your component and also simplify the api for the component.
|
|
958
|
+
|
|
959
|
+
Multiple components can be yielded with the `hash` and `component` helper:
|
|
960
|
+
|
|
961
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
962
|
+
import Banner from '../components/banner';
|
|
963
|
+
|
|
964
|
+
<template>
|
|
965
|
+
<Banner @value={{@model}} as |banner|>
|
|
966
|
+
<banner.Title>Banner title</banner.Title>
|
|
967
|
+
<banner.Subtitle>Banner subtitle</banner.Subtitle>
|
|
968
|
+
<banner.Body>A load of body text</banner.Body>
|
|
969
|
+
</Banner>
|
|
970
|
+
</template>
|
|
971
|
+
```
|
|
972
|
+
|
|
973
|
+
```gjs {data-filename="app/components/banner.gjs"}
|
|
974
|
+
import Title from './banner/title';
|
|
975
|
+
import Subtitle from './banner/subtitle';
|
|
976
|
+
import Body from './banner/body';
|
|
977
|
+
|
|
978
|
+
export default class Banner extends Component {
|
|
979
|
+
Title = Title;
|
|
980
|
+
Subtitle = Subtitle;
|
|
981
|
+
Body = Body;
|
|
982
|
+
|
|
983
|
+
<template>
|
|
984
|
+
<div>
|
|
985
|
+
{{yield (hash
|
|
986
|
+
Title=this.Title
|
|
987
|
+
Subtitle=this.Subtitle
|
|
988
|
+
Body=(component this.Body defaultArg="some value")
|
|
989
|
+
)}}
|
|
990
|
+
</div>
|
|
991
|
+
</template>
|
|
992
|
+
}
|
|
993
|
+
```
|
|
994
|
+
|
|
995
|
+
Result:
|
|
996
|
+
|
|
997
|
+
```html
|
|
998
|
+
<div>
|
|
999
|
+
<h1>Banner title</h1>
|
|
1000
|
+
<h2>Banner subtitle</h2>
|
|
1001
|
+
A load of body text
|
|
1002
|
+
</div>
|
|
1003
|
+
```
|
|
1004
|
+
|
|
1005
|
+
A benefit of using this pattern is that the user of the component can change the order the components are displayed.
|
|
1006
|
+
|
|
1007
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
1008
|
+
import Banner from '../components/banner';
|
|
1009
|
+
|
|
1010
|
+
<template>
|
|
1011
|
+
<Banner @value={{@model}} as |banner|>
|
|
1012
|
+
<banner.Subtitle>Banner subtitle</banner.Subtitle>
|
|
1013
|
+
<banner.Title>Banner title</banner.Title>
|
|
1014
|
+
<banner.Body>A load of body text</banner.Body>
|
|
1015
|
+
</Banner>
|
|
1016
|
+
</template>
|
|
1017
|
+
```
|
|
1018
|
+
|
|
1019
|
+
Result:
|
|
1020
|
+
|
|
1021
|
+
```html
|
|
1022
|
+
<div>
|
|
1023
|
+
<h2>Banner subtitle</h2>
|
|
1024
|
+
<h1>Banner title</h1>
|
|
1025
|
+
A load of body text
|
|
1026
|
+
</div>
|
|
1027
|
+
```
|
|
1028
|
+
|
|
1029
|
+
Another benefit to using `yield` with the `hash` and `component` helper
|
|
1030
|
+
is you can pass attributes and arguments to these components:
|
|
1031
|
+
|
|
1032
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
1033
|
+
import Banner from '../components/banner';
|
|
1034
|
+
|
|
1035
|
+
<template>
|
|
1036
|
+
<Banner @value={{@model}} as |banner|>
|
|
1037
|
+
<banner.Subtitle class="mb-1">Banner subtitle</banner.Subtitle>
|
|
1038
|
+
<banner.Title @variant="loud">Banner title</banner.Title>
|
|
1039
|
+
<banner.Body>A load of body text</banner.Body>
|
|
1040
|
+
</Banner>
|
|
1041
|
+
</template>
|
|
1042
|
+
```
|
|
1043
|
+
|
|
1044
|
+
```gjs {data-filename="app/components/banner/subtitle.gjs"}
|
|
1045
|
+
{{!-- note the use of ..attributes --}}
|
|
1046
|
+
<h2 ...attributes>
|
|
1047
|
+
{{yield}}
|
|
1048
|
+
</h2>
|
|
1049
|
+
```
|
|
1050
|
+
|
|
1051
|
+
```gjs {data-filename="app/components/banner/title.gjs"}
|
|
1052
|
+
<template>
|
|
1053
|
+
{{#if (eq @variant "loud")}}
|
|
1054
|
+
<h1 class="loud">{{yield}}</h1>
|
|
1055
|
+
{{else}}
|
|
1056
|
+
<h1 class="quiet">{{yield}}</h1>
|
|
1057
|
+
{{/if}}
|
|
1058
|
+
</template>
|
|
1059
|
+
```
|
|
1060
|
+
|
|
1061
|
+
Result:
|
|
1062
|
+
|
|
1063
|
+
```html
|
|
1064
|
+
<div>
|
|
1065
|
+
<h2 class="mb-1">Banner subtitle</h2>
|
|
1066
|
+
<h1 class="loud">Banner title</h1>
|
|
1067
|
+
A load of body text
|
|
1068
|
+
</div>
|
|
1069
|
+
```
|
|
1070
|
+
|
|
1071
|
+
`yield` is available as a keyword and does not need to be imported.
|
|
1072
|
+
|
|
1073
|
+
@method yield
|
|
1074
|
+
@param {Hash} options
|
|
1075
|
+
@return {String} HTML string
|
|
1076
|
+
@static
|
|
1077
|
+
@for Keywords
|
|
1078
|
+
@noimport
|
|
1079
|
+
@public
|
|
1080
|
+
*/
|
|
1081
|
+
/**
|
|
1082
|
+
`{{(has-block)}}` indicates if the component was invoked with a block.
|
|
1083
|
+
|
|
1084
|
+
This component is invoked with a block:
|
|
1085
|
+
|
|
1086
|
+
```handlebars
|
|
1087
|
+
<MyComponent>
|
|
1088
|
+
Hi Jen!
|
|
1089
|
+
</MyComponent>
|
|
1090
|
+
```
|
|
1091
|
+
|
|
1092
|
+
This component is invoked without a block:
|
|
1093
|
+
|
|
1094
|
+
```handlebars
|
|
1095
|
+
<MyComponent />
|
|
1096
|
+
```
|
|
1097
|
+
|
|
1098
|
+
This is useful when you want to create a component that can optionally take a block
|
|
1099
|
+
and then render a default template when it is not invoked with a block.
|
|
1100
|
+
|
|
1101
|
+
```gjs {data-filename="app/components/my-component.gjs"}
|
|
1102
|
+
<template>
|
|
1103
|
+
{{#if (has-block)}}
|
|
1104
|
+
Welcome {{yield}}, we are happy you're here!
|
|
1105
|
+
{{else}}
|
|
1106
|
+
Hey you! You're great!
|
|
1107
|
+
{{/if}}
|
|
1108
|
+
</template>
|
|
1109
|
+
```
|
|
1110
|
+
|
|
1111
|
+
`has-block` is available as a keyword and does not need to be imported.
|
|
1112
|
+
|
|
1113
|
+
@method has-block
|
|
1114
|
+
@param {String} blockName the name of the block. The name is either "main" or "inverse" (though only curly components support inverse) or the name given to a named block.
|
|
1115
|
+
@return {Boolean} `true` if the component was invoked with a block
|
|
1116
|
+
@static
|
|
1117
|
+
@for Keywords
|
|
1118
|
+
@noimport
|
|
1119
|
+
@public
|
|
1120
|
+
*/
|
|
1121
|
+
/**
|
|
1122
|
+
`{{(has-block-params)}}` indicates if the component was invoked with block params.
|
|
1123
|
+
|
|
1124
|
+
This component is invoked with block params:
|
|
1125
|
+
|
|
1126
|
+
```handlebars
|
|
1127
|
+
<MyComponent as |favoriteFlavor|>
|
|
1128
|
+
Hi Jen!
|
|
1129
|
+
</MyComponent>
|
|
1130
|
+
```
|
|
1131
|
+
|
|
1132
|
+
And without block params:
|
|
1133
|
+
|
|
1134
|
+
```handlebars
|
|
1135
|
+
<MyComponent>
|
|
1136
|
+
Hi Jen!
|
|
1137
|
+
</MyComponent>
|
|
1138
|
+
```
|
|
1139
|
+
|
|
1140
|
+
This is useful when you want to create a component that can render itself
|
|
1141
|
+
differently when it is not invoked with block params.
|
|
1142
|
+
|
|
1143
|
+
```gjs {data-filename="app/components/my-component.gjs"}
|
|
1144
|
+
<template>
|
|
1145
|
+
{{#if (has-block-params)}}
|
|
1146
|
+
Welcome {{yield this.favoriteFlavor}}, we're happy you're here and hope you
|
|
1147
|
+
enjoy your favorite ice cream flavor.
|
|
1148
|
+
{{else}}
|
|
1149
|
+
Welcome {{yield}}, we're happy you're here, but we're unsure what
|
|
1150
|
+
flavor ice cream you would enjoy.
|
|
1151
|
+
{{/if}}
|
|
1152
|
+
</template>
|
|
1153
|
+
```
|
|
1154
|
+
|
|
1155
|
+
@method has-block-params
|
|
1156
|
+
@static
|
|
1157
|
+
@for Keywords
|
|
1158
|
+
@noimport
|
|
1159
|
+
@param {String} blockName the name of the block. The name is either "main" or "inverse" (though only curly components support inverse) or the name given to a named block.
|
|
1160
|
+
@return {Boolean} `true` if the component was invoked with block params
|
|
1161
|
+
@public
|
|
1162
|
+
*/
|
|
1163
|
+
/**
|
|
1164
|
+
Execute the `debugger` statement in the current template's context.
|
|
1165
|
+
|
|
1166
|
+
```handlebars
|
|
1167
|
+
{{debugger}}
|
|
1168
|
+
```
|
|
1169
|
+
|
|
1170
|
+
When using the debugger helper you will have access to a `get` function. This
|
|
1171
|
+
function retrieves values available in the context of the template.
|
|
1172
|
+
For example, if you're wondering why a value `{{foo}}` isn't rendering as
|
|
1173
|
+
expected within a template, you could place a `{{debugger}}` statement and,
|
|
1174
|
+
when the `debugger;` breakpoint is hit, you can attempt to retrieve this value:
|
|
1175
|
+
|
|
1176
|
+
```
|
|
1177
|
+
> get('foo')
|
|
1178
|
+
```
|
|
1179
|
+
|
|
1180
|
+
`get` is also aware of keywords. So in this situation
|
|
1181
|
+
|
|
1182
|
+
```handlebars
|
|
1183
|
+
{{#each this.items as |item|}}
|
|
1184
|
+
{{debugger}}
|
|
1185
|
+
{{/each}}
|
|
1186
|
+
```
|
|
1187
|
+
|
|
1188
|
+
You'll be able to get values from the current item:
|
|
1189
|
+
|
|
1190
|
+
```
|
|
1191
|
+
> get('item.name')
|
|
1192
|
+
```
|
|
1193
|
+
|
|
1194
|
+
You can also access the context of the view to make sure it is the object that
|
|
1195
|
+
you expect:
|
|
1196
|
+
|
|
1197
|
+
```
|
|
1198
|
+
> context
|
|
1199
|
+
```
|
|
1200
|
+
|
|
1201
|
+
@method debugger
|
|
1202
|
+
@static
|
|
1203
|
+
@for Keywords
|
|
1204
|
+
@noimport
|
|
1205
|
+
@public
|
|
1206
|
+
*/
|
|
1207
|
+
/**
|
|
1208
|
+
The `component` helper is used to package a Component with initial arguments.
|
|
1209
|
+
The included arguments can then be merged during the final invocation.
|
|
1210
|
+
|
|
1211
|
+
See [Component](/ember/release/modules/@glimmer%2Fcomponent/) for
|
|
1212
|
+
additional information on how a `Component` functions.
|
|
1213
|
+
|
|
1214
|
+
This is similar to the concept of Partial Application.
|
|
1215
|
+
|
|
1216
|
+
For example, given a `FullName` component:
|
|
1217
|
+
|
|
1218
|
+
```gjs {data-filename="app/components/full-name.gjs"}
|
|
1219
|
+
import MyInputComponent from './my-input-component';
|
|
1220
|
+
|
|
1221
|
+
<template>
|
|
1222
|
+
{{yield (component MyInputComponent value=@model.name placeholder="Username")}}
|
|
1223
|
+
</template>
|
|
1224
|
+
```
|
|
1225
|
+
|
|
1226
|
+
The yielded component can be invoked by the calling component.
|
|
1227
|
+
See the following snippet:
|
|
1228
|
+
|
|
1229
|
+
```gjs {data-filename="app/components/person-form.gjs"}
|
|
1230
|
+
import FullName from './full-name';
|
|
1231
|
+
|
|
1232
|
+
<template>
|
|
1233
|
+
<FullName @model={{@model}} as |Field|>
|
|
1234
|
+
<Field />
|
|
1235
|
+
</FullName>
|
|
1236
|
+
</template>
|
|
1237
|
+
```
|
|
1238
|
+
|
|
1239
|
+
Which will output an input whose value is already bound to `@model.name` and `placeholder`
|
|
1240
|
+
is "Username".
|
|
1241
|
+
|
|
1242
|
+
Any arguments passed at the invocation site of the component will override those applied via
|
|
1243
|
+
the `component` helper. For example, if the invocation site of the component is:
|
|
1244
|
+
|
|
1245
|
+
```gjs {data-filename="app/components/person-form.gjs"}
|
|
1246
|
+
import FullName from './full-name';
|
|
1247
|
+
|
|
1248
|
+
<template>
|
|
1249
|
+
<FullName @model={{@model}} as |Field|>
|
|
1250
|
+
<Field @placeholder="Your name" />
|
|
1251
|
+
</FullName>
|
|
1252
|
+
</template>
|
|
1253
|
+
```
|
|
1254
|
+
|
|
1255
|
+
The output will be an input whose value is bound to `@model.name` and `placeholder`
|
|
1256
|
+
is "Your name".
|
|
1257
|
+
|
|
1258
|
+
The `component` helper is built-in and does not need to be imported.
|
|
1259
|
+
|
|
1260
|
+
Prior to Strict Mode aka "Template Tag" or gjs, the component helper was also used to invoke
|
|
1261
|
+
components dynamically. This is no longer necessary, and they can be directly invoked, as above.
|
|
1262
|
+
|
|
1263
|
+
### Dynamic Component Invocation
|
|
1264
|
+
|
|
1265
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
1266
|
+
import Component from '@glimmer/component';
|
|
1267
|
+
import { tracked } from '@glimmer/tracking';
|
|
1268
|
+
import { component } from '@ember/helper';
|
|
1269
|
+
import LiveUpdatingChart from '../components/live-updating-chart';
|
|
1270
|
+
import MarketCloseSummary from '../components/market-close-summary';
|
|
1271
|
+
|
|
1272
|
+
export default class Application extends Component {
|
|
1273
|
+
@tracked isMarketOpen = false;
|
|
1274
|
+
|
|
1275
|
+
get infographicComponent() {
|
|
1276
|
+
return this.isMarketOpen ? LiveUpdatingChart : MarketCloseSummary;
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
<template>
|
|
1280
|
+
{{!-- The component can be invoked directly --}}
|
|
1281
|
+
<this.infographicComponent />
|
|
1282
|
+
|
|
1283
|
+
{{!-- The component helper here is no longer necessary --}}
|
|
1284
|
+
{{component this.infographicComponentName}}
|
|
1285
|
+
</template>
|
|
1286
|
+
}
|
|
1287
|
+
```
|
|
1288
|
+
|
|
1289
|
+
@method component
|
|
1290
|
+
@since 1.11.0
|
|
1291
|
+
@static
|
|
1292
|
+
@for Keywords
|
|
1293
|
+
@noimport
|
|
1294
|
+
@public
|
|
1295
|
+
*/
|
|
1296
|
+
/**
|
|
1297
|
+
Use the `{{helper}}` helper to create contextual helper so
|
|
1298
|
+
that it can be passed around as first-class values in templates.
|
|
1299
|
+
|
|
1300
|
+
```handlebars
|
|
1301
|
+
{{#let (helper "join-words" "foo" "bar" separator=" ") as |foo-bar|}}
|
|
1302
|
+
|
|
1303
|
+
{{!-- this is equivalent to invoking `{{join-words "foo" "bar" separator=" "}}` --}}
|
|
1304
|
+
{{foo-bar}}
|
|
1305
|
+
|
|
1306
|
+
{{!-- this will pass the helper itself into the component, instead of invoking it now --}}
|
|
1307
|
+
<MyComponent @helper={{helper foo-bar "baz"}} />
|
|
1308
|
+
|
|
1309
|
+
{{!-- this will yield the helper itself ("contextual helper"), instead of invoking it now --}}
|
|
1310
|
+
{{yield foo-bar}}
|
|
1311
|
+
{{/let}}
|
|
1312
|
+
```
|
|
1313
|
+
|
|
1314
|
+
### Arguments
|
|
1315
|
+
|
|
1316
|
+
The `{{helper}}` helper works similarly to the [`{{component}}`](./component?anchor=component) and
|
|
1317
|
+
[`{{modifier}}`](./modifier?anchor=modifier) helper:
|
|
1318
|
+
|
|
1319
|
+
* When passed a string (e.g. `(helper "foo")`) as the first argument,
|
|
1320
|
+
it will produce an opaque, internal "helper definition" object
|
|
1321
|
+
that can be passed around and invoked elsewhere.
|
|
1322
|
+
|
|
1323
|
+
* Any additional positional and/or named arguments (a.k.a. params and hash)
|
|
1324
|
+
will be stored ("curried") inside the definition object, such that, when invoked,
|
|
1325
|
+
these arguments will be passed along to the referenced helper.
|
|
1326
|
+
|
|
1327
|
+
|
|
1328
|
+
@method helper
|
|
1329
|
+
@static
|
|
1330
|
+
@for Keywords
|
|
1331
|
+
@noimport
|
|
1332
|
+
@public
|
|
1333
|
+
@since 3.27.0
|
|
1334
|
+
*/
|
|
1335
|
+
/**
|
|
1336
|
+
The `if` helper allows you to conditionally render one of two branches,
|
|
1337
|
+
depending on the "truthiness" of a property.
|
|
1338
|
+
For example the following values are all falsey: `false`, `undefined`, `null`, `""`, `0`, `NaN` or an empty array.
|
|
1339
|
+
|
|
1340
|
+
This helper has two forms, block and inline.
|
|
1341
|
+
|
|
1342
|
+
## Block form
|
|
1343
|
+
|
|
1344
|
+
You can use the block form of `if` to conditionally render a section of the template.
|
|
1345
|
+
|
|
1346
|
+
To use it, pass the conditional value to the `if` helper,
|
|
1347
|
+
using the block form to wrap the section of template you want to conditionally render.
|
|
1348
|
+
Like so:
|
|
1349
|
+
|
|
1350
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
1351
|
+
import Weather from '../components/weather';
|
|
1352
|
+
|
|
1353
|
+
<template>
|
|
1354
|
+
<Weather />
|
|
1355
|
+
</template>
|
|
1356
|
+
```
|
|
1357
|
+
|
|
1358
|
+
```gjs {data-filename="app/components/weather.gjs"}
|
|
1359
|
+
<template>
|
|
1360
|
+
{{! will not render because greeting is undefined}}
|
|
1361
|
+
{{#if @isRaining}}
|
|
1362
|
+
Yes, grab an umbrella!
|
|
1363
|
+
{{/if}}
|
|
1364
|
+
</template>
|
|
1365
|
+
```
|
|
1366
|
+
|
|
1367
|
+
You can also define what to show if the property is falsey by using
|
|
1368
|
+
the `else` helper.
|
|
1369
|
+
|
|
1370
|
+
```gjs {data-filename="app/components/weather.gjs"}
|
|
1371
|
+
<template>
|
|
1372
|
+
{{#if @isRaining}}
|
|
1373
|
+
Yes, grab an umbrella!
|
|
1374
|
+
{{else}}
|
|
1375
|
+
No, it's lovely outside!
|
|
1376
|
+
{{/if}}
|
|
1377
|
+
</template>
|
|
1378
|
+
```
|
|
1379
|
+
|
|
1380
|
+
You are also able to combine `else` and `if` helpers to create more complex
|
|
1381
|
+
conditional logic.
|
|
1382
|
+
|
|
1383
|
+
For the following template:
|
|
1384
|
+
|
|
1385
|
+
```gjs {data-filename="app/components/weather.gjs"}
|
|
1386
|
+
<template>
|
|
1387
|
+
{{#if @isRaining}}
|
|
1388
|
+
Yes, grab an umbrella!
|
|
1389
|
+
{{else if @isCold}}
|
|
1390
|
+
Grab a coat, it's chilly!
|
|
1391
|
+
{{else}}
|
|
1392
|
+
No, it's lovely outside!
|
|
1393
|
+
{{/if}}
|
|
1394
|
+
</template>
|
|
1395
|
+
```
|
|
1396
|
+
|
|
1397
|
+
If you call it by saying `isCold` is true:
|
|
1398
|
+
|
|
1399
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
1400
|
+
import Weather from '../components/weather';
|
|
1401
|
+
|
|
1402
|
+
<template>
|
|
1403
|
+
<Weather @isCold={{true}} />
|
|
1404
|
+
</template>
|
|
1405
|
+
```
|
|
1406
|
+
|
|
1407
|
+
Then `Grab a coat, it's chilly!` will be rendered.
|
|
1408
|
+
|
|
1409
|
+
## Inline form
|
|
1410
|
+
|
|
1411
|
+
The inline `if` helper conditionally renders a single property or string.
|
|
1412
|
+
|
|
1413
|
+
In this form, the `if` helper receives three arguments, the conditional value,
|
|
1414
|
+
the value to render when truthy, and the value to render when falsey.
|
|
1415
|
+
|
|
1416
|
+
For example, if `useLongGreeting` is truthy, the following:
|
|
1417
|
+
|
|
1418
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
1419
|
+
import Greeting from '../components/greeting';
|
|
1420
|
+
|
|
1421
|
+
<template>
|
|
1422
|
+
<Greeting @useLongGreeting={{true}} />
|
|
1423
|
+
<template>
|
|
1424
|
+
```
|
|
1425
|
+
|
|
1426
|
+
```gjs {data-filename="app/components/greeting.gjs"}
|
|
1427
|
+
<template>
|
|
1428
|
+
{{if @useLongGreeting "Hello" "Hi"}} Alex
|
|
1429
|
+
<template>
|
|
1430
|
+
```
|
|
1431
|
+
|
|
1432
|
+
Will render:
|
|
1433
|
+
|
|
1434
|
+
```html
|
|
1435
|
+
Hello Alex
|
|
1436
|
+
```
|
|
1437
|
+
|
|
1438
|
+
One detail to keep in mind is that both branches of the `if` helper will be evaluated,
|
|
1439
|
+
so if you have `{{if condition "foo" (expensive-operation "bar")`,
|
|
1440
|
+
`expensive-operation` will always calculate.
|
|
1441
|
+
|
|
1442
|
+
`if` is built-in and does not need to be imported.
|
|
1443
|
+
|
|
1444
|
+
@method if
|
|
1445
|
+
@static
|
|
1446
|
+
@for Keywords
|
|
1447
|
+
@noimport
|
|
1448
|
+
@public
|
|
1449
|
+
*/
|
|
1450
|
+
/**
|
|
1451
|
+
The `unless` helper is the inverse of the `if` helper. It displays if a value
|
|
1452
|
+
is falsey ("not true" or "is false"). Example values that will display with
|
|
1453
|
+
`unless`: `false`, `undefined`, `null`, `""`, `0`, `NaN` or an empty array.
|
|
1454
|
+
|
|
1455
|
+
## Inline form
|
|
1456
|
+
|
|
1457
|
+
The inline `unless` helper conditionally renders a single property or string.
|
|
1458
|
+
This helper acts like a ternary operator. If the first property is falsy,
|
|
1459
|
+
the second argument will be displayed, otherwise, the third argument will be
|
|
1460
|
+
displayed
|
|
1461
|
+
|
|
1462
|
+
For example, if you pass a falsey `useLongGreeting` to the `Greeting` component:
|
|
1463
|
+
|
|
1464
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
1465
|
+
import Greeting from '../components/greeting';
|
|
1466
|
+
|
|
1467
|
+
<template>
|
|
1468
|
+
<Greeting @useLongGreeting={{false}} />
|
|
1469
|
+
</template>
|
|
1470
|
+
```
|
|
1471
|
+
|
|
1472
|
+
```gjs {data-filename="app/components/greeting.gjs"}
|
|
1473
|
+
<template>
|
|
1474
|
+
{{unless @useLongGreeting "Hi" "Hello"}} Ben
|
|
1475
|
+
</template>
|
|
1476
|
+
```
|
|
1477
|
+
|
|
1478
|
+
Then it will display:
|
|
1479
|
+
|
|
1480
|
+
```html
|
|
1481
|
+
Hi Ben
|
|
1482
|
+
```
|
|
1483
|
+
|
|
1484
|
+
## Block form
|
|
1485
|
+
|
|
1486
|
+
Like the `if` helper, the `unless` helper also has a block form.
|
|
1487
|
+
|
|
1488
|
+
The following will not render anything:
|
|
1489
|
+
|
|
1490
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
1491
|
+
import Greeting from '../components/greeting';
|
|
1492
|
+
|
|
1493
|
+
<template>
|
|
1494
|
+
<Greeting />
|
|
1495
|
+
</template>
|
|
1496
|
+
```
|
|
1497
|
+
|
|
1498
|
+
```gjs {data-filename="app/components/greeting.gjs"}
|
|
1499
|
+
<template>
|
|
1500
|
+
{{#unless @greeting}}
|
|
1501
|
+
No greeting was found. Why not set one?
|
|
1502
|
+
{{/unless}}
|
|
1503
|
+
</template>
|
|
1504
|
+
```
|
|
1505
|
+
|
|
1506
|
+
You can also use an `else` helper with the `unless` block. The
|
|
1507
|
+
`else` will display if the value is truthy.
|
|
1508
|
+
|
|
1509
|
+
If you have the following component:
|
|
1510
|
+
|
|
1511
|
+
```gjs {data-filename="app/components/logged-in.gjs"}
|
|
1512
|
+
<template>
|
|
1513
|
+
{{#unless @userData}}
|
|
1514
|
+
Please login.
|
|
1515
|
+
{{else}}
|
|
1516
|
+
Welcome back!
|
|
1517
|
+
{{/unless}}
|
|
1518
|
+
</template>
|
|
1519
|
+
```
|
|
1520
|
+
|
|
1521
|
+
Calling it with a truthy `userData`:
|
|
1522
|
+
|
|
1523
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
1524
|
+
import LoggedIn from '../components/logged-in';
|
|
1525
|
+
|
|
1526
|
+
<template>
|
|
1527
|
+
<LoggedIn @userData={{hash username="Zoey"}} />
|
|
1528
|
+
</template>
|
|
1529
|
+
```
|
|
1530
|
+
|
|
1531
|
+
Will render:
|
|
1532
|
+
|
|
1533
|
+
```html
|
|
1534
|
+
Welcome back!
|
|
1535
|
+
```
|
|
1536
|
+
|
|
1537
|
+
and calling it with a falsey `userData`:
|
|
1538
|
+
|
|
1539
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
1540
|
+
import LoggedIn from '../components/logged-in';
|
|
1541
|
+
|
|
1542
|
+
<template>
|
|
1543
|
+
<LoggedIn @userData={{false}} />
|
|
1544
|
+
</template>
|
|
1545
|
+
```
|
|
1546
|
+
|
|
1547
|
+
Will render:
|
|
1548
|
+
|
|
1549
|
+
```html
|
|
1550
|
+
Please login.
|
|
1551
|
+
```
|
|
1552
|
+
|
|
1553
|
+
`unless` is built-in and does not need to be imported.
|
|
1554
|
+
|
|
1555
|
+
@method unless
|
|
1556
|
+
@for Keywords
|
|
1557
|
+
@noimport
|
|
1558
|
+
@static
|
|
1559
|
+
@public
|
|
1560
|
+
*/
|
|
1561
|
+
/**
|
|
1562
|
+
`log` allows you to output the value of variables in the current rendering
|
|
1563
|
+
context. `log` also accepts primitive types such as strings or numbers.
|
|
1564
|
+
|
|
1565
|
+
```handlebars
|
|
1566
|
+
{{log "myVariable:" myVariable }}
|
|
1567
|
+
```
|
|
1568
|
+
|
|
1569
|
+
`log` is built-in as a template keyword and does not need to be imported.
|
|
1570
|
+
|
|
1571
|
+
@method log
|
|
1572
|
+
@for Keywords
|
|
1573
|
+
@noimport
|
|
1574
|
+
@static
|
|
1575
|
+
@param {Array} params
|
|
1576
|
+
@public
|
|
1577
|
+
*/
|
|
1578
|
+
/**
|
|
1579
|
+
Use the `{{modifier}}` helper to create contextual modifier so
|
|
1580
|
+
that it can be passed around as first-class values in templates.
|
|
1581
|
+
|
|
1582
|
+
```handlebars
|
|
1583
|
+
{{#let (modifier "click-outside" click=this.submit) as |on-click-outside|}}
|
|
1584
|
+
|
|
1585
|
+
{{!-- this is equivalent to `<MyComponent {{click-outside click=this.submit}} />` --}}
|
|
1586
|
+
<MyComponent {{on-click-outside}} />
|
|
1587
|
+
|
|
1588
|
+
{{!-- this will pass the modifier itself into the component, instead of invoking it now --}}
|
|
1589
|
+
<MyComponent @modifier={{modifier on-click-outside "extra" "args"}} />
|
|
1590
|
+
|
|
1591
|
+
{{!-- this will yield the modifier itself ("contextual modifier"), instead of invoking it now --}}
|
|
1592
|
+
{{yield on-click-outside}}
|
|
1593
|
+
{{/let}}
|
|
1594
|
+
```
|
|
1595
|
+
|
|
1596
|
+
### Arguments
|
|
1597
|
+
|
|
1598
|
+
The `{{modifier}}` helper works similarly to the [`{{component}}`](./component?anchor=component) and
|
|
1599
|
+
[`{{helper}}`](./helper?anchor=helper) helper:
|
|
1600
|
+
|
|
1601
|
+
* When passed a string (e.g. `(modifier "foo")`) as the first argument,
|
|
1602
|
+
it will produce an opaque, internal "modifier definition" object
|
|
1603
|
+
that can be passed around and invoked elsewhere.
|
|
1604
|
+
|
|
1605
|
+
* Any additional positional and/or named arguments (a.k.a. params and hash)
|
|
1606
|
+
will be stored ("curried") inside the definition object, such that, when invoked,
|
|
1607
|
+
these arguments will be passed along to the referenced modifier.
|
|
1608
|
+
|
|
1609
|
+
`modifier` is built-in as a template keyword and does not need to be imported.
|
|
1610
|
+
|
|
1611
|
+
@method modifier
|
|
1612
|
+
@for Keywords
|
|
1613
|
+
@static
|
|
1614
|
+
@public
|
|
1615
|
+
@since 3.27.0
|
|
1616
|
+
*/
|
|
1617
|
+
/**
|
|
1618
|
+
`pageTitle` allows you to set the title of any page in your application and
|
|
1619
|
+
append additional titles for each route. For complete documentation, see
|
|
1620
|
+
https://github.com/ember-cli/ember-page-title.
|
|
1621
|
+
|
|
1622
|
+
```gjs
|
|
1623
|
+
import { pageTitle } from 'ember-page-title';
|
|
1624
|
+
|
|
1625
|
+
<template>
|
|
1626
|
+
{{pageTitle "My Page Title" }}
|
|
1627
|
+
</template>
|
|
1628
|
+
```
|
|
1629
|
+
|
|
1630
|
+
@method pageTitle
|
|
1631
|
+
@for External
|
|
1632
|
+
@param {String} param
|
|
1633
|
+
@static
|
|
1634
|
+
@public
|
|
1635
|
+
*/
|
|
1636
|
+
/**
|
|
1637
|
+
The `let` helper receives one or more positional arguments and yields
|
|
1638
|
+
them out as block params.
|
|
1639
|
+
|
|
1640
|
+
This allows the developer to introduce shorter names for certain computations
|
|
1641
|
+
in the template.
|
|
1642
|
+
|
|
1643
|
+
This is especially useful if you are passing properties to a component
|
|
1644
|
+
that receives a lot of options and you want to clean up the invocation.
|
|
1645
|
+
|
|
1646
|
+
For the following example, the template receives a `post` object with
|
|
1647
|
+
`content` and `title` properties.
|
|
1648
|
+
|
|
1649
|
+
We are going to call the `my-post` component, passing a title which is
|
|
1650
|
+
the title of the post suffixed with the name of the blog, the content
|
|
1651
|
+
of the post, and a series of options defined in-place.
|
|
1652
|
+
|
|
1653
|
+
```handlebars
|
|
1654
|
+
{{#let
|
|
1655
|
+
(concat post.title ' | The Ember.js Blog')
|
|
1656
|
+
post.content
|
|
1657
|
+
(hash
|
|
1658
|
+
theme="high-contrast"
|
|
1659
|
+
enableComments=true
|
|
1660
|
+
)
|
|
1661
|
+
as |title content options|
|
|
1662
|
+
}}
|
|
1663
|
+
<MyPost @title={{title}} @content={{content}} @options={{options}} />
|
|
1664
|
+
{{/let}}
|
|
1665
|
+
```
|
|
1666
|
+
|
|
1667
|
+
`let` is built-in and does not need to be imported.
|
|
1668
|
+
|
|
1669
|
+
@method let
|
|
1670
|
+
@static
|
|
1671
|
+
@noimport
|
|
1672
|
+
@for Keywords
|
|
1673
|
+
@public
|
|
1674
|
+
*/
|
|
1675
|
+
/**
|
|
1676
|
+
The `in-element` helper renders its block content outside of the regular flow,
|
|
1677
|
+
into a DOM element given by its `destinationElement` positional argument.
|
|
1678
|
+
|
|
1679
|
+
Common use cases - often referred to as "portals" or "wormholes" - are rendering
|
|
1680
|
+
dropdowns, modals or tooltips close to the root of the page to bypass CSS overflow
|
|
1681
|
+
rules, or to render content to parts of the page that are outside of the control
|
|
1682
|
+
of the Ember app itself (e.g. embedded into a static or server rendered HTML page).
|
|
1683
|
+
|
|
1684
|
+
```handlebars
|
|
1685
|
+
{{#in-element this.destinationElement}}
|
|
1686
|
+
<div>Some content</div>
|
|
1687
|
+
{{/in-element}}
|
|
1688
|
+
```
|
|
1689
|
+
|
|
1690
|
+
### Arguments
|
|
1691
|
+
|
|
1692
|
+
`{{in-element}}` requires a single positional argument:
|
|
1693
|
+
|
|
1694
|
+
- `destinationElement` -- the DOM element to render into. It must exist at the time
|
|
1695
|
+
of rendering.
|
|
1696
|
+
|
|
1697
|
+
It also supports an optional named argument:
|
|
1698
|
+
|
|
1699
|
+
- `insertBefore` -- by default the DOM element's content is replaced when used as
|
|
1700
|
+
`destinationElement`. Passing `null` to `insertBefore` changes the behaviour to
|
|
1701
|
+
append the block content to the end of any existing content. Any other value than
|
|
1702
|
+
`null` is currently not supported.
|
|
1703
|
+
|
|
1704
|
+
For example:
|
|
1705
|
+
|
|
1706
|
+
```handlebars
|
|
1707
|
+
{{#in-element this.destinationElement insertBefore=null}}
|
|
1708
|
+
<div>Some content</div>
|
|
1709
|
+
{{/in-element}}
|
|
1710
|
+
```
|
|
1711
|
+
|
|
1712
|
+
`in-element` is built-in and does not need to be imported.
|
|
1713
|
+
|
|
1714
|
+
@method in-element
|
|
1715
|
+
@for Keywords
|
|
1716
|
+
@param {Element} destinationElement the DOM element to render into. It must exist at the time
|
|
1717
|
+
of rendering.
|
|
1718
|
+
@param {Boolean} insertBefore named argument, by default the DOM element's content is replaced when used as
|
|
1719
|
+
`destinationElement`. Passing `null` to `insertBefore` changes the behaviour to
|
|
1720
|
+
append the block content to the end of any existing content. Any other value than
|
|
1721
|
+
`null` is currently not supported.
|
|
1722
|
+
@static
|
|
1723
|
+
@noimport
|
|
1724
|
+
@public
|
|
1725
|
+
*/
|
|
686
1726
|
}
|