Home > Article > Web Front-end > Introduction to the life cycle of JS controls_javascript skills
JS控件的生命周期跟其他平台UI的生命周期类似,但是又有自己的特点,我们只有将控件的生命周期划分清晰,所有的控件编写、mixins的编写和plugin的编写才能遵循控件的生命周期做统一的管理。在这里我把JS的生命周期定义为4部分:
1.initializer: 初始化,做一些不牵扯DOM操作的初始化操作
2.createDom: 创建 DOM,在这个过程中我们创建控件需要的DOM结构
3.renderUI: 生成控件的内部元素,在这里调用子控件的渲染方法,开启子控件的生命周期
4.bindUI: 绑定事件,可以绑定子控件事件也可以绑定内部DOM的事件
5.synUI: DOM结构以及子控件生成完毕后,我们在配置项中传入的值或者默认的配置项要应用到DOM上,例如 width,height,focusable之类的属性
6.destructor: 析构函数,移除控件,清理控件上的事件,清理子控件,清理控件自己的DOM以及控件的一些对其他控件的引用。
Figure 1
Initialization:
Do the following during the initialization process of the control:
1. Call the inherited parent class Initialization function, including parent classes and mixins on the prototype chain
2. Process configuration items, merge default configuration items and configuration items passed in by the user
3. Process events bound to the changed object
4. Initialization plug-in (plugin)
After the initialization is completed, whether to create DOM depends on the specific strategy. Similar to the implementation of ext, you can delay the creation of DOM
Create DOM
The process of creating DOM is as follows:
1. Call the DOM creation function of the inherited parent class, including the parent class and mixins on the prototype chain
2. Create the DOM of the control
3. Call the creation of the control plug-in The execution process of DOM functions
rendering sub-controls and internal DOM operations
is as follows:
1. Call the rendering function of the parent class, including the parent class and mixins on the prototype chain
2. Call the plug-in’s rendering function
We can initialize the child control in the top-level parent class. The advantage is that the subclass does not need to initialize the sub-control. At this time:
1. If the sub-control has not been initialized, perform initialization
2. Continue to create the DOM of the sub-control, render the sub-control, and bind events. , Synchronous configuration item function execution
Binding events
Since the DOM of the control and the internal sub-controls have been rendered at this time, you can bind events on the sub-controls or DOM. The process of binding events:
1. Call the binding event method of the parent class, including the parent class and mixins on the prototype chain
2. Call the binding event method of the plug-in
Note: in When binding events on sub-controls or internal DOM, use delegation. Do not directly bind events on sub-controls or DOM. Once sub-controls are added or deleted, changes in the internal DOM will cause the event to fail.
Synchronized configuration items
First of all, let’s explain what synchronized configuration items are. We have already done some processing on the configuration items when initializing the control (as for how to process them) , which will be discussed later when we talk about JS control properties), but the configuration items do not affect the DOM or internal sub-controls.
Why synchronization is processed at this time instead of when creating DOM and rendering sub-controls, there are 2 reasons:
1. When creating DOM and rendering sub-controls, all DOM and sub-controls are not completely generated. Time synchronization requires a lot of judgment
2. We need to extract the work of synchronizing configuration items into methods. When the configuration items are modified, the internal DOM and sub-controls will change accordingly.
For example: the configuration item has { width : 100 }
1. If we synchronize when rendering the DOM, we may set "width=100px;" directly to the DOM, but we need to modify it For this width, we also need to write a function to set this value.
2. On the contrary, we centralize the synchronization configuration items and extract the process of synchronizing each configuration item into functions. Then our process of initializing width and modifying width are exactly the same, so that the concept and logic are unified. stand up.
The process of synchronizing configuration items is still the same as other steps:
1. Call the synchronization method of the parent class, including the parent class and mixins on the prototype chain
2. Call the synchronization method of the plug-in
Note: We should be able to configure whether a configuration item is synchronized at this time. There are many reasons. For example, multiple configuration items will produce the same operation. If multiple configuration items are synchronized at the same time, then a process will be executed multiple times.
Remove the control
Any object has a constructor, and it must also have a destructor, but this function is often the most overlooked place, but it is also a very important place, let alone problems such as memory leaks. , that is, if the removal of a control is not done well enough, it will cause great trouble to normal use.
This function is the most difficult one to write, because it needs to handle the following work:
1. Clean up other controls used. Whether to also remove them depends on the specific situation. Distinguish between association and aggregation
2. Clean up child controls
3. Clean up events bound to controls and DOM
4. Remove DOM
5. Clean up variable references, this is more troublesome and cumbersome , so we need to uniformly manage the references of controls
The same function must also be executed:
1. Call the destructor of the parent class, including the parent class and mixins on the prototype chain
2. Call Plug-in's destructor
Problems
All the above are specific steps, but a series of problems were encountered during implementation:
1. There are problems with calling parent class methods
1) To call parent class methods on the prototype chain, you can only use methods such as className.superclass.method.call(this), this.constructor.superclass.method.call(this ) cannot be used. The reason is mentioned in the extend chapter of js control inheritance. This calling method is cumbersome and inconvenient to maintain.
2) Call the method on mixins. In the chapter of JS inheriting mixins, I talked about the implementation principle of mixins. Overwriting the method with the same name. The method of mixins is actually a method on the prototype of the control, so it is best not to use the same name. Method, if multiple mixins use methods such as renderUI and synUI, and the controls inheriting these mixins do not implement methods such as renderUI, they will be overwritten.
2. There are also problems with the method of calling the plug-in
1) We need to get a reference to the current control
Solution:
1. For calling the parent For class methods, when rendering the control, we can first call the parent class method and then the subclass method in the order of the prototype chain until the current control:
As shown in the inheritance relationship above, When we execute C.renderUI(), we execute it from the top of the inheritance prototype chain downwards.
2. To execute the minxins method, when we execute renderUI, we execute the __renderUI method of the mixin in sequence.
3. When executing the renderUI of the parent class, if mixins also exist, execute the __renderUI method of the mixin.
Picture 3
As shown in the picture above: inherits represents prototype chain inheritance, and extends represents mixin extension
Then the execution process of c.renderUI is as follows:
A.renderUI ->D.__renderUI->B. renderUI->E.__renderUI->C.renderUI
3. When calling the plug-in method, you need to pass the reference of the control itself, such as:
plugin1.render(this)
4. Destructor Destructor comparison envoys, the order of execution is different from the order mentioned in 2 above:
Subclass destructor -> Subclass extension destructor -> Parent class destructor -> Parent class extension destructor
Follow Figure 3 The order of execution of destructors of an inheritance structure is:
C. destructor ->E.__destructor->B.destructor->E.__destructor->a.destructor
The reason is that subclasses Some references depend on the parent class or extended class. If the parent class and extended class execute the destructor first, the subclass will report an error when using certain variables/properties.
In this section I talked about the life cycle of controls. All of them are from UIBase of the KISSY framework. If you are interested, you can take a look. It is a very exciting implementation http://docs.kissyui.com/kissy/docs/#!/api/KISSY.Component.UIBase