3

ExtJSは初めてです。アプリケーションでタブ機能を使用およびカスタマイズしようとしています。

JavascriptスコープからExtJsスコープにあるパラメーターを使用して関数を呼び出したい。今のところ、エラーが発生することなく、パラメーターを渡さずに関数を呼び出すことができます。パラメータ(コードに記載)を渡して同じ関数を呼び出すと、関数が値を取得していないため、次のエラーが発生します。

Uncaught TypeError: Cannot call method 'indexOf' of null

この関数は、タブパネルに新しいタブを追加する必要があります。

ExtJSスコープからパラメーターを渡して同じ関数を呼び出すと、タブが正常に追加されます。ただし、パラメーターを渡してjavascriptスコープから関数が呼び出される場合はそうではありません。この問題を理解して修正するのを手伝ってください。

Ext.onReady(function() {
var currentItem;
var tabs = Ext.widget('tabpanel', {
    launch: function() {
      _myAppGlobal = this;
    },
    renderTo: 'tabs',
    resizeTabs: true,
    enableTabScroll: true,
    width: 850,
    defaults: {
        autoScroll: true,
        bodyPadding: 10
    }], 
    plugins: Ext.create('Ext.ux.TabCloseMenu', {
        extraItemsTail: [
            '-',
            {
                text: 'Closable',
                checked: true,
                hideOnClick: true,
                handler: function (item) {
                    currentItem.tab.setClosable(item.checked);
                }
            },
            '-',
            {
                text: 'Enabled',
                checked: true,
                hideOnClick: true,
                handler: function(item) {
                    currentItem.tab.setDisabled(!item.checked);
                }
            }
        ],
        listeners: {
            aftermenu: function () {
                currentItem = null;
            },
            beforemenu: function (menu, item) {
                menu.child('[text="Closable"]').setChecked(item.closable);
                menu.child('[text="Enabled"]').setChecked(!item.tab.isDisabled());

                currentItem = item;
            }
        }
    })
  });

  function addTab_inside(closeable, tabtitle, targetUrl) {
      tabs.add({
          title: tabtitle,
          iconCls: 'tabs',
          autoLoad: {url: targetUrl, callback: this.initSearch, scope: this},
          closable: closeable,
          autoScroll: true,
          nocache: true,
          discardUrl: false
      }).show();
  }
});

function addTab_Outside(){
   addTab_inside(true, 'Test', 'test.php');
}

addTab_Outside関数はイベントベースであり、xyz要素でonClickが呼び出されます。

4

2 に答える 2

2

Extスコープのようなものはありません。ExtはJSオブジェクトと関数のセットであり、それ以上の機能はありません。そのため、JSに適用できるものはすべてExtに適用できます。スコープの問題と複雑さは、純粋にJavaScriptの問題であり、Extと他のJSライブラリまたはユーティリティとの違いはありません。

さて、あなたがしたことを見てみましょう:

  1. いくつかのパラメーターを使用してExt.onReady()関数を呼び出しました。
  2. グローバルスコープ(別名ウィンドウスコープ)で関数addTab_Outside()を定義しました。

以上です。

次に、addTab_Outside関数を見てみましょう。この関数では、別の関数addTab_insideを呼び出しています。しかし、この「内部」関数はどこにありますか?JSはこの関数をどこで探す必要がありますか?グローバルスコープで「ouside」関数を定義しているため、JSは同じスコープで内部関数を検索し、グローバルスコープで作成されていないため、その関数を見つけることができません。

では、「内部」関数はどのスコープで作成されますか?さて、ここで最初に行ったこと、Ext.onReady()関数呼び出しに戻りましょう。この関数を呼び出して、単一のパラメーターを渡しました。currentItemそのパラメーターは、2つのローカル変数と。を持つ無名関数ですtabs。また、「addTab_inside」という名前のローカル関数も作成しました。私が「ローカル」と言うとき、それは変数がそれらが作成されたスコープの関数に対してローカルであることを意味します。あなたの場合、その親関数は匿名であるため、アドレス指定できません。もちろん、その関数内のローカル変数はすべて同じスコープ内にあるため、相互にアクセスできます。currentItem'タブ'参照'関数内'またはあなたが大丈夫である限り。

ソリューションが機能する唯一の方法は、外部関数を大きな無名関数ブロック内に移動することです。しかし、本当に理由がないので、あなたはそれをしたくないのではないかと思います。

このスコープの説明を理解することは重要ですが、私の直感では、何をしようとしても、別のアプローチに従う必要があります。完全なアプリケーションを構築している場合は、Senchaガイドで概説されているアプリケーション構造を使用し、コントローラーとフォルダー構造を使用してコードを分離することをお勧めします。

于 2013-03-07T07:17:53.033 に答える
1

addTab_inside(true, 'Test', 'test.php');Ext.onReadyの前に実行されます。したがって、関数はまだ存在しません。addTab_insideをExt.onReadyメソッドの下部に移動します。

アップデート

@dbrinは、ここでスコープの問題を説明する素晴らしい仕事をしました。自分のアプローチを実際に機能させたい場合は、以下に示すように、いくつかの「名前空間」を設定する必要があります。

//Namespace defined in Global scope
var myApp = {};

Ext.onReady(function(){ 
  //Some stuff... 

  myApp.addTab_inside = function(closeable, tabtitle, targetUrl){
    //do work
  }
});

function addTab_Outside(){
  myApp.addTab_inside(true, 'Test', 'test.php');
}

addTab_inside前に述べたように、 Extの準備が整う前に電話をかけないようにする必要があります。

そうは言っても、@dbrinが述べたように提案されたMVCアーキテクチャに関するチュートリアルをチェックすることをお勧めします。

于 2013-03-06T17:44:21.753 に答える