Guide applies to: modern

Introduction

In this lab, you’ll create the dialog window that shows the iTunes music video preview.

1.Create the Dialog class

Create the file app/desktop/src/view/Preview.js using this code:

  1. Ext.define('ModernTunes.view.Preview', {
  2. extend: 'Ext.Dialog',
  3. xtype: 'preview',
  4. resizable: true,
  5. closable: true,
  6. bodyPadding: 16,
  7. width: 640,
  8. height: 480
  9. });

2.Detect a click on a thumbnail in the dataview or on a record in the grid

Observe the listeners config on the instances. This is how we can ‘listen’ to

Edit app/desktop/src/view/main/MainView.js and add this select listener to the dataview:

  1. {
  2. xtype: 'tunesview',
  3. listeners: {
  4. select: 'onThumbSelect'
  5. },
  6. bind: {
  7. store: '{tunes}'
  8. }
  9. }

… and do the same for the grid:

  1. {
  2. xtype: 'tunesgrid',
  3. listeners: {
  4. select: 'onGridSelect'
  5. },
  6. bind: {
  7. store: '{tunes}'
  8. }
  9. }

Now edit app/desktop/src/view/main/MainViewontroller.js and add the onThumbSelect and onGridSelect event handlers with simple console logs to the artist field in the record:

  1. onThumbSelect: function(thumbs, record) {
  2. console.log(record.data.artist);
  3. },
  4. onGridSelect: function(grid, records) {
  5. console.log(records[0].data.artist);
  6. }

Lab: Code the Modern Dialog Handler - 图1

Notice that each event handler has a different function signature to reference the current record, but both are to perform the same action: displaying the video. So to reach the video field we are looking to render in the Dialog, in app/desktop/src/view/main/MainCViewontroller.js we will compose a function we will call onShowPreview that will instantiate an instance of the Preview class we just defined:

  1. onShowPreview: function (record) {
  2. var vid = Ext.create({
  3. xtype: 'preview'
  4. });
  5. vid.show();
  6. }

Dialogs do not show automatically, you have to run the show() method on the instance of the dialog (similiar to the autoLoad property we have on a store instance).

We will the call the onShowPreview function from both event handlers (replacing the console logs), passing in the appropriate reference (dataview and grid records are passed in different ways):

  1. onThumbSelect: function(thumbs, record) {
  2. this.onShowPreview(record);
  3. },
  4. onGridSelect: function(grid, records) {
  5. this.onShowPreview(records[0]);
  6. }

Remember, you can’t use a class without loading it and adding the file to the build. That means you also need to add a requires array entry for Tunes.view.Preview to MainViewController.js.

  1. requires: [
  2. 'ModernTunes.view.Preview'
  3. ],

Save and refresh in the browser, and the method creates a placeholder instance of Tunes.view.Preview regardless of the tab from which it is called.

Lab: Code the Modern Dialog Handler - 图2 Lab: Code the Modern Dialog Handler - 图3

3.Render the video in the Dialog container

To render the video and the svg iTunes image link in the dialog, in the onShowPreview function in MainViewController we will compose an items array containing instances of each in a simple layout:

  • first, an instance of the video, using the record object to access the preview video url itself and the placeholder image posterUrl

    1. var videoConfig = {
    2. xtype: 'video',
    3. url: record.data.preview,
    4. posterUrl: record.data.image
    5. };
  • next, an instance of a generic component that uses the itunesstore field from the current record

    1. var linkConfig = {
    2. docked: 'bottom',
    3. xtype: 'component',
    4. data: {
    5. itunesstore: record.data.itunesstore
    6. }
    7. };
  • finally, create an instance of a generic container that will have the previous two instances (+videoConfig+ and linkConfig) as children to its items array

    1. var containerConfig = { // parent container of the video and the anchor/link
    2. xtype: 'container',
    3. title: record.data.title + ' — ' + record.data.artist,
    4. style: '{background-color: black;}',
    5. layout: 'fit',
    6. items: [
    7. videoConfig,
    8. linkConfig
    9. ]
    10. };

    Then, we can revise our previous vid variable to be the following:

    1. var vid = Ext.create({ // instance of the Preview Dialog class displaying the container
    2. xtype: 'preview',
    3. title: record.data.title,
    4. layout: 'fit',
    5. items: [containerConfig],
    6. });
    7. vid.show();
  • So as you can see our revised instance of Preview has an items array added that has as its sole child an istance of the container of the current video instance and the button linking back to iTunes for the current song.

Save, and review the revised version of the app in the browser. Click on a thumbnail, click on a record and try it out! That’s awesome!

Lab: Code the Modern Dialog Handler - 图4

4.By the way …

  • a minor modification of the code is to check if the current video has been called already (repeat clicks on the same record) and if has, do not call another instance of the same one. We will place this as the first line of the function.
  1. onShowPreview: function(record) {
  2. if (this.getView().down('video')) {
  3. return;
  4. }
  5. ...
  6. }

5.This is the finished code

  1. Ext.define('ModernTunes.view.main.MainViewController', {
  2. extend: 'Ext.app.ViewController',
  3. alias: 'controller.mainviewcontroller',
  4. requires: [
  5. 'ModernTunes.view.Preview'
  6. ],
  7. onShowPreview: function(record) {
  8. if (this.getView().down('video')) {
  9. return;
  10. }
  11. var videoConfig = { // instance of the video
  12. xtype: 'video',
  13. url: record.data.preview,
  14. posterUrl: record.data.image
  15. };
  16. var linkConfig = { // instance of the anchor/link back to iTunes
  17. docked: 'bottom',
  18. xtype: 'component',
  19. tpl: [
  20. '<a href="{itunesstore}" target="itunes_store">',
  21. '<img src="resources/images/get-it-itunes.svg" style="margin: 16px; display: block; margin-left: auto; margin-right: auto; width: 75px;">',
  22. '</a>'
  23. ],
  24. data: {
  25. itunesstore: record.data.itunesstore
  26. }
  27. };
  28. var containerConfig = { // parent container of the video and the anchor/link
  29. xtype: 'container',
  30. title: record.data.title + ' — ' + record.data.artist,
  31. style: '{background-color: black;}',
  32. layout: 'fit',
  33. items: [
  34. videoConfig,
  35. linkConfig
  36. ]
  37. };
  38. var vid = Ext.create({ // instance of the Preview Dialog class displaying the container
  39. xtype: 'preview',
  40. title: record.data.title,
  41. layout: 'fit',
  42. items: [containerConfig],
  43. });
  44. vid.show();
  45. },
  46. onThumbSelect: function(thumbs, record) {
  47. this.onShowPreview(record);
  48. },
  49. onGridSelect: function(grid, records) {
  50. this.onShowPreview(records[0]);
  51. }
  52. });