基于react开发苍穹自定义控件原创
金蝶云社区-路边明
路边明
2人赞赏了该文章 49次浏览 未经作者许可,禁止转载编辑于2024年11月05日 14:41:02
summary-icon摘要由AI智能服务提供

本文介绍了一个使用React开发简单城市管理应用的需求背景,详细阐述了苍穹自定义控件的实现原理。具体包括:使用苍穹新版脚手架初始化React工程,扩展全局window对象并添加KDApi,定义了一个setHtml函数用于设置HTML内容并渲染React组件,同时加载CSS文件和处理状态更新。最后提示了打包上传后的调试注意点。

需求背景:使用react开发一个简单的城市管理,包括增删查改功能。 


苍穹自定义控件的实现原理  :  苍穹平台把自定义空间的dom标签插入到苍穹的自定义控件代码下面 


一、使用苍穹新版脚手架初始化工程,选择react得到基础的工程


二、

prodindex.tsx 组件解释

//扩展全局window对象

//将KDApi添加到全局window对象中,这样它就可以在模块内部被访问。

declare global {

  interface Window {
    KDApi: TKDApi
  }




; (function (KDApi: TKDApi) {
  function MyComponent(this: ComponentInstance, model: TCustomModel) {
    this._setModel(model)
  }

立即执行函数表达式(Immediately Invoked Function Expression,IIFE),它是一种在定义后立即执行的JavaScript函数。这种模式常用于创建局部作用域,避免污染全局命名空间,并且可以立即执行代码。  

  1. 分号(;

    • 分号是语句终止符。在这里,它用于确保在函数表达式之前的任何代码已经正确结束,避免由于缺少分号导致的潜在错误。

  2. 函数表达式

    • (function (KDApi: TKDApi) { ... })定义了一个匿名函数,它接受一个参数KDApi,并且这个参数被指定为TKDApi类型。这里的TKDApi是一个类型注解,用于TypeScript,表示KDApi参数应该符合TKDApi接口的定义。

  3. 函数体

    • 在函数的大括号{}内部,你可以放置任何代码。在这个例子中,代码定义了一个名为MyComponent的类,以及一些与KDApi交互的逻辑。

  4. 立即执行

    • 函数定义后,紧跟着的(window.KDApi)是函数的调用,这意味着函数会立即执行。window.KDApi作为参数传递给函数内部的KDApi参数。

  5. window.KDApi

    • 这是全局window对象上的一个属性,它被传递给函数作为参数。这意味着函数内部可以通过KDApi访问到window.KDApi对象,从而使用它提供的方法和属性。


var setHtml = function (model: TCustomModel, customProps: TCustomProps) {
    const files = './css/index.css'
    KDApi.loadFile(files, model, () => {
      const Root = (props: IRoot) => {
        const { model, customProps } = props

        const [newCustomProps, setNewCustomProps] = useState(customProps)
        const [cityData, setCityData] = useState()

        useEffect(() => {
          const updateSub = eventBus.sub(model!, 'update', (updateProps: any) => {
            setNewCustomProps(updateProps)

          })

          const updatecity = eventBus.sub(model!, 'handleDirective', (updateProps: any) => {
            setCityData(updateProps)

          })
          return () => {
            eventBus.unsub(updateSub)
          }
        }, [])


        return (
          <div data-control-name="city_management">
            <App model={model} customProps={newCustomProps} />
          </div>
        )
      }
      ReactDOM.render(<Root model={model} customProps={customProps} />, model.dom)
    })

  }

 `setHtml` 负责设置HTML内容并渲染一个React组件。


1. 函数定义:

   - `var setHtml = function (model: TCustomModel, customProps: TCustomProps) { ... }`

   - 这行代码定义了一个名为 `setHtml` 的函数,它接受两个参数:`model` 和 `customProps`。`model` 是一个自定义模型对象,`customProps` 是自定义属性对象。


2. 加载CSS文件:

   - `const files = './css/index.css'`

   - 声明一个常量 `files`,包含CSS文件的路径。


3. 异步加载文件:

   - `KDApi.loadFile(files, model, () => { ... })`

   - 使用 `KDApi` 对象的 `loadFile` 方法异步加载CSS文件。当文件加载完成后,回调函数会被执行。


4. 定义React组件:

   - `const Root = (props: IRoot) => { ... }`

   - 在回调函数内部,定义了一个名为 `Root` 的React函数组件,它接受 `props` 参数,这个参数包含了 `model` 和 `customProps`。


5. 解构props:

   - `const { model, customProps } = props`

   - 从 `props` 中解构出 `model` 和 `customProps`。


6. 使用React状态钩子:

   -`const [newCustomProps, setNewCustomProps] = useState(customProps)`

   - 使用 `useState` 钩子创建一个状态 `newCustomProps`,并用 `customProps` 初始化它。同时,`setNewCustomProps` 是一个函数,用于更新这个状态。

   - `const [cityData, setCityData] = useState()`

   - 同样使用 `useState` 钩子创建另一个状态 `cityData`,初始值为 `undefined`。`setCityData` 是更新这个状态的函数。


这段代码的目的是设置HTML内容,包括加载CSS文件,并定义一个React组件 `Root`,这个组件使用了一些状态来存储和更新自定义属性和城市数据。这个组件稍后会被渲染到DOM中。


注意点: 

这个前端工程打包后上传到自定义控件中的是一个压缩包,包括index.js 和css文件夹, 如果发现html能够正常渲染但是没有任何样式,需要回来检查是不是prod组件的css文件加载没写好,如果没有写好就会出现以上情况, 本地调试不会出现这个情况,因为本地调试用的是devIndex.tsx文件

const files = './css/index.css'
    KDApi.loadFile(files, model, () => {


图标赞 2
2人点赞
还没有人点赞,快来当第一个点赞的人吧!
图标打赏
0人打赏
还没有人打赏,快来当第一个打赏的人吧!