序章
複雑なWebプロジェクトでは、多くの場合、サードパーティのウィジェットを使用する必要があります。 しかし、フレームワークを使用していて、ウィジェットが純粋なJavaScriptでのみ利用可能である場合はどうでしょうか。
プロジェクトでJavaScriptウィジェットを使用するには、フレームワーク固有のラッパーを作成するのが最善の方法です。
ag-Grid は、データグリッドに情報を表示するためのJavaScriptウィジェットです。 これにより、情報を動的に並べ替え、フィルタリング、および選択できます。 ag-Grid
Reactラッパーも提供します。 ag-grid-react
.
この記事では、 ag-grid-community
と ag-grid-react
サードパーティのウィジェットをReactコンポーネントにラップする方法を学ぶための基礎として。 ReactPropsとウィジェットの構成オプションの間のマッピングを設定します。 また、Reactコンポーネントを介してウィジェットのAPIを公開します。
前提条件
この記事をフォローするには、次のものが必要です。
- Reactにある程度精通している。 React.jsシリーズのコーディング方法をご覧ください。
ステップ1—JavaScriptウィジェットを理解する
一般に、ほとんどのJavaScriptウィジェットには次のものがあります。
- 構成オプション
- パブリックAPI
- 放送されたイベント
それはまさにあなたが対話する方法です ag-Grid
. グリッドのプロパティ、イベント、コールバック、およびAPI の適切な説明は、公式ドキュメントにあります。
つまり、データグリッドは次のことを定義します。
- グリッドプロパティは、行アニメーションなどのグリッドの機能を有効にします。
- グリッドAPIは、実行時にグリッドと対話します(たとえば、選択したすべての行を取得します)
- グリッドイベント行の並べ替えや行の選択など、グリッドで特定のイベントが発生したときにグリッドから発行されます
- グリッドコールバックは、必要なときにアプリケーションからグリッドに情報を提供するために使用されます(たとえば、メニューが表示されるたびにコールバックが呼び出され、アプリケーションがメニューをカスタマイズできるようになります)
グリッドオプションの使用法を示す非常に基本的な純粋なJavaScript構成を次に示します。
let gridOptions = {
// PROPERTIES - object properties, myRowData and myColDefs are created somewhere in your application
rowData: myRowData,
columnDefs: myColDefs,
// PROPERTIES - simple boolean / string / number properties
pagination: true,
rowSelection: 'single',
// EVENTS - add event callback handlers
onRowClicked: function(event) { console.log('a row was clicked'); },
onColumnResized: function(event) { console.log('a column was resized'); },
onGridReady: function(event) { console.log('the grid is now ready'); },
// CALLBACKS
isScrollLag: function() { return false; }
}
まず、JavaScriptデータグリッドは次のように初期化されます。
new Grid(this._nativeElement, this.gridOptions, ...);
それで、 ag-Grid
APIメソッドを使用してオブジェクトをにアタッチします gridOptions
JavaScriptデータグリッドを制御するために使用できます。
// get the grid to refresh
gridOptions.api.refreshView();
ただし、 ag-Grid
Reactコンポーネントとして使用されるため、データグリッドを直接インスタンス化することはありません。 それがラッパーコンポーネントの仕事です。 のインスタンスとのすべての相互作用 ag-Grid
コンポーネントインスタンスを介して発生します。
たとえば、グリッドによってアタッチされたAPIオブジェクトに直接アクセスすることはできません。 コンポーネントのインスタンスを介してアクセスします。
ステップ2—ラッパーコンポーネントが何をすべきかを決定する
構成オプションとコールバックをグリッドに直接渡すことはありません。 Reactラッパーコンポーネントは、ReactPropsを介してオプションとコールバックを受け取ります。
バニラJavaScriptグリッドで使用できるすべてのグリッドオプションは、 Reactdatagridでも使用できる必要があります。 また、インスタンスのイベントを直接リッスンしません ag-Grid
. 使用している場合 ag-Grid
Reactコンポーネントとして、 ag-Grid
Reactコンポーネントの小道具から利用できるはずです。
これはすべて、React固有のデータグリッドラッパーが周りにあることを意味します ag-Grid
したほうがいい:
- 入力バインディング間のマッピングを実装します(
rowData
) とag-Grid
の構成オプション - によって発行されたイベントをリッスンする必要があります
ag-Grid
それらをコンポーネント出力として定義します - コンポーネントの入力バインディングの変更をリッスンし、グリッドの構成オプションを更新します
- によって添付されたAPIを公開する
ag-Grid
にgridOptions
そのプロパティを介して
次の例は、ReactPropsを使用してテンプレートでReactデータグリッドを構成する方法を示しています。
<AgGridReact
// useful for accessing the component directly via ref - optional
ref="agGrid"
// simple attributes, not bound to any state or prop
rowSelection="multiple"
// these are bound props, so can use anything in React state or props
columnDefs={this.props.columnDefs}
showToolPanel={this.state.showToolPanel}
// this is a callback
isScrollLag={this.myIsScrollLagFunction}
// these are registering event callbacks
onCellClicked={this.onCellClicked}
onColumnResized={this.onColumnEvent}
// inside onGridReady, you receive the grid APIs if you want them
onGridReady={this.onGridReady}
/>
要件を理解したので、次の場所でどのように実装したかを見てみましょう。 ag-Grid
.
ステップ3—ReactWrapperを実装する
まず、テンプレートでReactデータグリッドを表すReactコンポーネントAgGridReactを定義する必要があります。 このコンポーネントはレンダリングします DIV
データグリッドのコンテナとして機能する要素。 ネイティブを手に入れるには DIV
Refs機能を使用する要素:
export class AgGridReact extends React.Component {
protected eGridDiv: HTMLElement;
render() {
return React.createElement("div", {
style: ...,
ref: e => {
this.eGridDiv = e;
}
}, ...);
}
}
インスタンス化する前に ag-Grid
、すべてのオプションも収集する必要があります。 全て ag-Grid
プロパティとイベントは、ReactPropsとして提供されます。 AgGridReact
成分。 The gridOptions
プロパティは、すべてのデータグリッドオプションを格納するために使用されます。 利用可能になり次第、Reactプロップからすべての構成オプションをコピーする必要があります。
そのために、copyAttributesToGridOptions関数を実装しました。 これは、あるオブジェクトから別のオブジェクトにプロパティをコピーするユーティリティ関数です。
export class ComponentUtil {
...
public static copyAttributesToGridOptions(gridOptions, component, ...) {
...
// copy all grid properties to gridOptions object
ComponentUtil.ARRAY_PROPERTIES
.concat(ComponentUtil.STRING_PROPERTIES)
.concat(ComponentUtil.OBJECT_PROPERTIES)
.concat(ComponentUtil.FUNCTION_PROPERTIES)
.forEach(key => {
if (typeof component[key] !== 'undefined') {
gridOptions[key] = component[key];
}
});
...
return gridOptions;
}
}
オプションはにコピーされます componentDidMount
すべての小道具が更新された後のライフサイクルメソッド。 これは、グリッドをインスタンス化するフックでもあります。 インスタンス化されるときにネイティブDOM要素をデータグリッドに渡す必要があるため、 DIV
refs機能を使用してキャプチャされた要素:
export class AgGridReact extends React.Component {
gridOptions: AgGrid.GridOptions;
componentDidMount() {
...
let gridOptions = this.props.gridOptions || {};
if (AgGridColumn.hasChildColumns(this.props)) {
gridOptions.columnDefs = AgGridColumn.mapChildColumnDefs(this.props);
}
this.gridOptions = AgGrid.ComponentUtil.copyAttributesToGridOptions(gridOptions, this.props);
new AgGrid.Grid(this.eGridDiv, this.gridOptions, gridParams);
this.api = this.gridOptions.api;
this.columnApi = this.gridOptions.columnApi;
}
}
上記のように、列として渡された子が存在するかどうかも確認し、列定義として構成オプションに追加します。
if (AgGridColumn.hasChildColumns(this.props)) {
gridOptions.columnDefs = AgGridColumn.mapChildColumnDefs(this.props);
}
ステップ4—グリッドプロパティの更新を同期する
グリッドが初期化されたら、データグリッドの構成オプションを更新するためにReactPropsへの変更を追跡する必要があります。 ag-Grid
それを行うためのAPIを実装します。 たとえば、 headerHeight
プロパティの変更があります setHeaderHeight
ヘッダーの高さを更新するメソッド。
Reactの用途 componentWillReceiveProps
変更についてコンポーネントに通知するライフサイクルメソッド。 ここに更新ロジックを配置します。
export class AgGridReact extends React.Component {
componentWillReceiveProps(nextProps: any) {
const changes = <any>{};
const changedKeys = Object.keys(nextProps);
changedKeys.forEach((propKey) => {
...
if (!this.areEquivalent(this.props[propKey], nextProps[propKey])) {
changes[propKey] = {
previousValue: this.props[propKey],
currentValue: nextProps[propKey]
};
}
});
AgGrid.ComponentUtil.getEventCallbacks().forEach((funcName: string) => {
if (this.props[funcName] !== nextProps[funcName]) {
changes[funcName] = {
previousValue: this.props[funcName],
currentValue: nextProps[funcName]
};
}
});
AgGrid.ComponentUtil.processOnChange(changes, this.gridOptions, this.api, this.columnApi);
}
}
基本的に、私たちはのリストを調べます ag-Grid
の構成プロパティとコールバックを確認し、それらのいずれかが変更されているかどうかを確認します。 すべての変更を changes
配列し、を使用してそれらを処理します processOnChange
方法。
この方法は2つのことを行います。 まず、React Propsの変更を確認し、 gridOptions
物体。 次に、APIメソッドを呼び出して、変更についてグリッドに通知します。
export class ComponentUtil {
public static processOnChange(changes, gridOptions, api, ...) {
...
// reflect the changes in the gridOptions object
ComponentUtil.ARRAY_PROPERTIES
.concat(ComponentUtil.OBJECT_PROPERTIES)
.concat(ComponentUtil.STRING_PROPERTIES)
.forEach(key => {
if (changes[key]) {
gridOptions[key] = changes[key].currentValue;
}
});
...
// notify Grid about the changes in header height
if (changes.headerHeight) {
api.setHeaderHeight(changes.headerHeight.currentValue);
}
// notify Grid about the changes in page size
if (changes.paginationPageSize) {
api.paginationSetPageSize(changes.paginationPageSize.currentValue);
}
...
}
}
ステップ5—APIを公開する
実行時のReactグリッドとの対話は、グリッドAPIを介して行われます。 列のサイズを調整したり、新しいデータソースを設定したり、選択したすべての行のリストを取得したりすることができます。 JavaScriptデータグリッドが開始されると、 api
グリッドオプションオブジェクトへのオブジェクト。 このオブジェクトを公開するには、コンポーネントインスタンスに割り当てます。
export class AgGridReact extends React.Component {
componentDidMount() {
...
new AgGrid.Grid(this.eGridDiv, this.gridOptions, gridParams);
this.api = this.gridOptions.api;
this.columnApi = this.gridOptions.columnApi;
}
}
以上です。
結論
このチュートリアルでは、バニラJavaScriptライブラリをReactフレームワーク内で機能するように適合させる方法を学びました。
このトピックの詳細については、「他のライブラリとの統合」に関する公式のReactドキュメントを参照してください。