Kendo Reactの記録


非常にハードなライブラリレコードもハードです

Teleikコンポーネントを使用して、企業内で特別な困難なケースを作成します.
  • WebEditorを使用する場合のハングル入力ホットスポット.
    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.getCustomEl
    const 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を使いましょう...無駄に導入して、本当に罪を受けました.