Kendo Reactの記録
非常にハードなライブラリレコードもハードです
Teleikコンポーネントを使用して、企業内で特別な困難なケースを作成します. WebEditorを使用する場合のハングル入力ホットスポット.
Teleik ProseMirrorという編集ライブラリを使用
WebEditorプロパティは、ユーザーが入力したコンテンツをWeb element tagに変換します.
この場合、select、option、inputなどのタグに問題が発生します.
attributeの加入はいくつかのプロジェクトに対して制御されていることがわかります.
では、韓国語入力の問題を処理してみましょう.次は完全なコードです
エディタを作成するときに、イベントハンドルの関数に追加のアクションを追加します.
英語とは異なり、ハングルは1つのカーソルに最大4つのキーを入力できます.
これは散文-mirror編集には適用されません.
ex:hello->5カーソル、さようなら->2カーソル、6回タイプ
Custom cellは以下のように適用できます.
グリッド構成部品.tsxの例
これは、GridComponent<->MainPageなどのデータを含むページとコンポーネント間で転送するためです.
コアは、dataIdxがなくても、カラムがcustom cellであればtrueに解放されるべきです.
なぜなら、一度falseの列が後で適用データが正しい領域に戻ると、
出力できません.
(最初にdataIdxにundefinedを入力するのは面白い...ハハハ)
それ以外にも我慢できないことがたくさんあります.後で追加します.
ライブラリはよくできていますが、多くの開発が必要です.
これならそのままmaterial-uiを使いましょう...無駄に導入して、本当に罪を受けました.
Teleikコンポーネントを使用して、企業内で特別な困難なケースを作成します.
Teleik ProseMirrorという編集ライブラリを使用
WebEditorプロパティは、ユーザーが入力したコンテンツをWeb element tagに変換します.
この場合、select、option、inputなどのタグに問題が発生します.
import { getAttributes, hasAttrs, getAttrs , hole} from "./schema_utils";
export const input = {
attrs: {
value: { default: "" },
style: { default: null },
contenteditable : {default : true},
type : {default : null},
checked : {default : false},
id : {default : null},
placeholder : {default : ""}
},
group:"block",
content : "inline*",
selectable: false,
parseDOM: [ {
tag: 'input',
getAttrs: (dom:any) => ({
value : dom.getAttribute('value'),
style: dom.getAttribute('style'),
contenteditable : dom.getAttribute('contenteditable'),
type : dom.getAttribute('type'),
checked : dom.getAttribute('checked'),
id : dom.getAttribute('id'),
placeholder : dom.getAttribute('placeholder')
})
} ],
toDOM: (node:any) => {
return [ 'input', getAttrs(node.attrs) ];
}
}
上記のコードは、inputtagに対応するノードを追加することによって作成される例の1つです.attributeの加入はいくつかのプロジェクトに対して制御されていることがわかります.
let nodes = schema.spec.nodes.addToEnd("select", select);
nodes = nodes.addToEnd("option", option);
nodes = nodes.addToEnd("textarea", textarea);
nodes = nodes.addToEnd("input", input);
以上のように適用します.では、韓国語入力の問題を処理してみましょう.次は完全なコードです
new EditorView({
mount : event.dom
},
{
...event.viewProps,
state : EditorState.create({ doc : doc, plugins }),
handleDOMEvents: {
// https://prosemirror.net/docs/ref/#view.EditorProps.handleDOMEvents
...event.viewProps.handleDOMEvents,
keydown: (_view : any, event:any) => {
const { code, target, ctrlKey } = event;
return (
(code === "Backspace" ||
code === "Delete" ||
(ctrlKey && code === "KeyA")) &&
target.nodeName === "INPUT"
);
},
input: (view : any, event:any) => {
const target = event.target;
try{
if (!event.isComposing && target.nodeName === "INPUT") {
const cursor = target.selectionStart;
const parent = target.parentNode;
const index = Array.from(parent.childNodes).indexOf(target);
const pos = view.posAtDOM(target);
var tr;
if(props.editdisabled){
return;
}
tr = view.state.tr.setNodeMarkup(pos-1, null, {
value: target.value,
type: target.getAttribute("type")
});
view.dispatch(tr);
const input = parent.childNodes.item(index);
input.focus();
input.setSelectionRange(cursor, cursor);
} else if(target.nodeName === "SELECT"){
const pos = view.posAtDOM(target);
let tr = view.state.tr.setNodeMarkup(pos-1, null, {
value : target.value,
id : target.id
});
for(var i=0;i<target.childNodes.length;i++){
const pos = view.posAtDOM(target.childNodes[i]);
target.childNodes[i].innerText
if(target.childNodes[i].value == target.value){
tr = tr.setNodeMarkup(pos-1, null, {
selected : "selected",
value : target.childNodes[i].value
});
} else {
tr = tr.setNodeMarkup(pos-1, null, {
value : target.childNodes[i].value
});
}
}
view.dispatch(tr);
}
}catch(err){console.log(err)}
}
}
});
上のコードでは簡単ですが、エディタを作成するときに、イベントハンドルの関数に追加のアクションを追加します.
英語とは異なり、ハングルは1つのカーソルに最大4つのキーを入力できます.
これは散文-mirror編集には適用されません.
ex:hello->5カーソル、さようなら->2カーソル、6回タイプ
// <- 현재 타이핑중이라면
event.iscomposing
// <- editor에서 클릭하여 커서가있는 타겟이 들어온다 이게 input 이라면
target.nodeName == "INPUT"
// 1. 매번 입력시마다 이전 커서 위치를 가져온다. (입력시마다 커서는 한칸씩 이동된다)
// 2. 현재 커서 위치를 이전 커서위치로 강제로 focus 한다.
const cursor = target.selectionStart;
const parent = target.parentNode;
const index = Array.from(parent.childNodes).indexOf(target);
const pos = view.posAtDOM(target);
var tr;
if(props.editdisabled){
return;
}
tr = view.state.tr.setNodeMarkup(pos-1, null, {
value: target.value,
type: target.getAttribute("type")
});
view.dispatch(tr);
const input = parent.childNodes.item(index);
input.focus();
input.setSelectionRange(cursor, cursor);
2.Kendo-React-Gridに顧客ユニットを適用する際に問題が発生
Custom cellは以下のように適用できます.
グリッド構成部品.tsxの例
<GridContainer .... >
<Column
key={idx}
headerClassName={headerClass[idx]}
className={rowClass[idx]}
field={raw}
title={props.titles[idx]}
filterable={false}
width={
keysWidth && keysWidth[idx]
? keysWidth[idx]
: undefined
}
// minResizableWidth={64}
cell={(e) => {
if (props.getCustomEl)
return props.getCustomEl(
idx,
e.dataIndex,
e.columnIndex,
e.dataItem,
e
);
return null;
}}
locked={isLocked}
/>
</GridContainer>
props.getCustomElconst getCustomEl = (
idx: number,
dataIdx?: number,
columnIdx?: number,
dataItem?: any,
props?: GridCellProps
) => {
if (dataIdx == undefined) {
// 해당 컬럼이 custom cell 로 지정된 컬럼이라면 true
if (customElIndexes.indexOf(idx) != -1) return true;
return false;
}
// dataIdx 가 undefiend 가 아닐경우 custom cell return
return <S.TableTd ...blahblah > </S.TableTd>;
}
まず、getCustomeelという名前の関数を作成する理由は、次のとおりです.これは、GridComponent<->MainPageなどのデータを含むページとコンポーネント間で転送するためです.
コアは、dataIdxがなくても、カラムがcustom cellであればtrueに解放されるべきです.
なぜなら、一度falseの列が後で適用データが正しい領域に戻ると、
出力できません.
(最初にdataIdxにundefinedを入力するのは面白い...ハハハ)
それ以外にも我慢できないことがたくさんあります.後で追加します.
ライブラリはよくできていますが、多くの開発が必要です.
これならそのままmaterial-uiを使いましょう...無駄に導入して、本当に罪を受けました.
Reference
この問題について(Kendo Reactの記録), 我々は、より多くの情報をここで見つけました https://velog.io/@juhojung/Kendo-React-에-대한-기록テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol