공예 키트 내부 - 구성 요소 및 구성 요소 ID가 구조를 덮고 노출하는 방법




소품
설명


이.보기
섀도우 호스트

this.shadow
그림자 뿌리

this.root
구성 요소 루트 기반template

this.view , this.shadowthis.root 는 모든 뷰의 최상위 클래스인 Craft.Core.Component 에서 정의하는 Craft.UI.View 의 기본 속성입니다.
this.view는 고유한 componentId를 갖는 구성 요소의 최상위 DOM 요소입니다. 이것은 구성 요소의 섀도우 호스트입니다.
this.shadow는 구성 요소의 섀도우 루트이며 개방 모드로 this.view(섀도우 호스트)에 연결됩니다.
this.root는 템플릿의 첫 번째 자식이며 this.shadow(섀도우 루트)에 추가됩니다.

템플릿은 Shadow Root 아래에 있습니다. 따라서 CSS 클래스 이름과 DOM ID는 craftkit 애플리케이션에서 충돌하지 않습니다. 이는 Component 정의를 캡슐화하여 편안한 OOP를 가능하게 하는 크래프트킷의 첫 번째 핵심 기술입니다.

예를 들어:

class Vehicle extends Craft.UI.View {
    whoami(){
        return this.shadow.getElementById('text').innerHTML;
    }
    style(componentId){
        return `
            .root { color:red; }
        `;
    }
    template(componentId){
        return `
            <div id="root" class="root">
                <span id="text">I'm Vehicle</span>
            </div>
        `;
    }
}
class Bike extends Vehicle {
    style(componentId){
        return super.style(componentId) + `
            .root { color:blue; }
        `;
    }
    template(componentId){
        return `
            <div id="root" class="root">
                <span id="text">I'm Bike.</span>
            </div>
        `;
    }
}
class Car extends Vehicle {
    style(componentId){
        return super.style(componentId) + `
            .root { color:purple; }
        `;
    }
    template(componentId){
        return `
            <div id="root" class="root">
                <span id="text">I'm Car.</span>
            </div>
        `;
    }
}


Bike와 Car는 둘 다 Vehicle의 CSS 클래스를 캐스케이드.root하지만 둘 다root 클래스는 독립적으로 적용되며 충돌하지 않습니다.

Shadow DOM 사양의 원칙에 따라 구성 요소 외부에서 해당 ID를 통해 구성 요소 DOM 요소 내부에 액세스할 수 없습니다.

그러나 원하는 곳에서 componentId를 통해 구성 요소 내부에 액세스할 수 있습니다.

인스턴스화된 구성 요소는 고유한 Craft.Core.ComponentStack에 의해 componentId에 등록됩니다. 부팅 시 Craft.Core.Defaults.ALLOW_COMPONENT_SHORTCUT를 true로 설정하면 componentId를 전역 변수로 사용할 수도 있습니다. 이것이 크래프트킷의 두 번째 핵심 기술입니다.

이 기능은 렌더링된 템플릿에서 인스턴스 메서드를 호출하는 데 사용됩니다.

class DangerousTruck extends Car {
    ignite(){
        this.shadow.getElementById('text').innerHTML = "🚛🔥🔥🔥";
    }
    cooldown(){
        this.shadow.getElementById('text').innerHTML = "I'm COOL Truck 😄";
    }
    style(componentId){
        return super.style(componentId) + `
            .root { color:purple; }
        `;
    }
    template(componentId){
        return `
            <div id="root" class="root">
                <span id="text" onclick="${componentId}.ignite()">
                    I'm dangerous Truck.
                </span>
            </div>
        `;
    }
}


텍스트를 클릭하면 트럭에 불이 들어옵니다!

물론 다음과 같이 전역에서 ignite 메서드를 호출할 수 있습니다.

Object.keys(Craft.Core.ComponentStack.container)
.filter( id => id.match('Dangerous') )
.map( danger => window[danger].cooldown() )


※ Craft.Core.ComponentStack.container의 Object.keys는 componentId의 배열을 반환합니다. 문자열입니다. 따라서 window 객체에서 접근하고 있습니다.

노트



위의 예는 놀이터에서 실행할 수 있습니다.

var bike_view = new Bike();
bike_view.loadView();
Craft.Core.Context.getRootViewController().appendSubView(bike_view);

var car_view = new Car();
car_view.loadView();
Craft.Core.Context.getRootViewController().appendSubView(car_view);

bike_view.shadow.getElementById('text').innerHTML; //-> I'm Bike
bike_view.whoami();                                //-> I'm Bike

car_view.root.style.color = 'purple' //-> make 'I'm Car.' purple

var truck_view = new DangerousTruck();
truck_view.loadView();
Craft.Core.Context.getRootViewController().appendSubView(truck_view);

truck_view.ignite(); //-> 🚛🔥🔥🔥


🛺 CraftKit 플레이그라운드 사용해보기:
https://github.com/craftkit/craftkit-playground

좋은 웹페이지 즐겨찾기