1# ArkTS Syntax Usage 2 3 4## How do I dynamically create components using code in ArkUI? (API version 9) 5 6**Solution** 7 8ArkUI uses the ArkTS declarative development paradigm. Developers cannot hold component instances. During declaration, you can control component creation by rendering control syntax and dynamically building UI elements. 9 10**Example** 11 12``` 13// Create a component using the if statement. 14if(this.isTrue) { 15 Text ("Create Text Component").fontSize (30) 16} 17// Create a component using the ForEach statement. 18ForEach(this.nums,(item) => { 19 Text(item + '').fontSize(30) 20},item => JSON.stringify(item)) 21``` 22 23**Reference** 24 25[Overview of Rendering Control](../quick-start/arkts-rendering-control-overview.md) 26 27 28## What is the difference between an @Builder decorated method and a regular method? (API version 9) 29 30**Solution** 31 32The \@Builder decorated method allows for use of a custom component, while regular methods do not. If a custom component is used in an @Builder decorated method, it is re-created each time the method is called. 33 34**Reference** 35 36[@BuilderParam](../quick-start/arkts-builderparam.md) 37 38 39## How do I define @BuilderParam decorated attributes? (API version 9) 40 41**Solution** 42 43- Without parameters 44 45 If no parameter is passed when you assign a value to the \@BuilderParam decorated attribute (for example, content: this.specificParam), define the type of the attribute as a function without a return value (for example, **\@BuilderParam content: () => void**). 46 47- With parameters 48 49 If any parameter is passed when you assign a value to the \@BuilderParam decorated attribute (for example, **callContent: this.specificParam1("111")**), define the type of the attribute as **any** (for example, **\@BuilderParam callContent: any**). 50 51**Reference** 52 53[@BuilderParam](../quick-start/arkts-builderparam.md) 54 55 56## How do I listen for object changes in an array? (API version 9) 57 58**Solution** 59 60To listen for object changes in an array, use the \@Observed and \@ObjectLink decorators. \@Observed applies to classes, and \@ObjectLink applies to variables. 61 62**Example** 63 641. Use \@Observed on a class. 65 66 ``` 67 @Observed 68 class ClassA { 69 public name: string 70 public c: number 71 public id: number 72 73 constructor(c: number, name: string = 'OK') { 74 this.name = name 75 this.c = c 76 } 77 } 78 ``` 79 802. Use \@ObjectLink on a component variable. 81 82 ``` 83 @Component 84 struct ViewA { 85 label: string = 'ViewA1' 86 @ObjectLink a: ClassA 87 88 build() { 89 Row() { 90 Button(`ViewA [${this.label}] this.a.c= ${this.a.c} +1`) 91 .onClick(() => { 92 this.a.c += 1 93 }) 94 }.margin({ top: 10 }) 95 } 96 } 97 ``` 98 99**Reference** 100 101[\@Observed and \@ObjectLink: Observing Property Changes in Nested Class Objects](../quick-start/arkts-observed-and-objectlink.md) 102 103 104## How do I transfer values through the parent component to \@Link decorated variables in a child component? (API version 9) 105 106**Solution** 107 108To enable a child component to receive the value from the parent component through \@Link, **'$'** must be used to first establish a reference relationship between variables in the child and parent components. 109 110**Example** 111 112The \@Link semantics are derived from the **'$'** operator. In other words, **\$isPlaying** enables two-way binding of the internal state **this.isPlaying**. When the button in the **PlayButton** child component is touched, the value of the @Link decorated variable is changed, and **PlayButton** together with the **Image** and **Text** components of the parent component is refreshed. Similarly, when the button in the parent component is touched, the value of **this.isPlaying** is changed, and **PlayButton** together with the **Text** and **Button** components of the parent component is refreshed. 113 1141. Use the \@State decorator in the parent component and use the **'$'** operator to create a reference for transferring data. 115 116 ``` 117 @Entry 118 @Component 119 struct Player { 120 @State isPlaying: boolean = false 121 build() { 122 Column() { 123 PlayButton({ buttonPlaying: $isPlaying }) 124 Text(`Player is ${this.isPlaying ? '' : 'not'} playing`).fontSize(18) 125 Button('Parent:' + this.isPlaying) 126 .margin(15) 127 .onClick(() => { 128 this.isPlaying = !this.isPlaying 129 }) 130 } 131 } 132 } 133 134 ``` 135 1362. Use @Link in the child component to receive data. 137 138 ``` 139 @Component 140 struct PlayButton { 141 @Link buttonPlaying: boolean 142 143 build() { 144 Column() { 145 Button(this.buttonPlaying ? 'pause' : 'play') 146 .margin(20) 147 .onClick(() => { 148 this.buttonPlaying = !this.buttonPlaying 149 }) 150 } 151 } 152 } 153 ``` 154 155**Reference** 156 157[@Link](../quick-start/arkts-link.md) 158 159 160## How does a component synchronize state with its grandchild components? (API version 9) 161 162**Solution** 163 164- Method 1 (recommended): Use the \@Provide and \@Consume decorators. Specifically, use \@Provide in the component and \@Consume in the grandchild component to implement two-way data binding between the components. 165 166- Method 2: Use the \@State and \@Link decorators. Specifically, use \@State in the parent component and \@Link in each layer of child components (child and grandchild components). 167 168**Example 1** 169 1701. Include a child component in the component. Employ @Provide in the component to provide the **reviewVote** parameter to its grandchild component. 171 172 ``` 173 @Entry 174 @Component 175 struct Father{ 176 @Provide("reviewVote") reviewVotes: number = 0; 177 178 build() { 179 Column() { 180 Son() 181 Button(`Father: ${this.reviewVotes}`) 182 ... 183 } 184 } 185 } 186 ``` 187 1882. Include the grandchild component in the child component. 189 190 ``` 191 @Component 192 struct Son{ 193 build() { 194 Column() { 195 GrandSon() 196 } 197 } 198 } 199 ``` 200 2013. Employ @Consume in the grandchild component to receive the **reviewVote** parameter. 202 203 ``` 204 @Component 205 struct GrandSon{ 206 @Consume("reviewVote") reviewVotes: number 207 208 build() { 209 Column() { 210 Button(`GrandSon: ${this.reviewVotes}`) 211 ... 212 }.width('100%') 213 } 214 } 215 ``` 216 217**Example 2** 218 2191. Decorate **reviewVote** with @State in the component **Father**. 220 221 ``` 222 @Entry 223 @Component 224 struct Father { 225 @State reviewVotes: number = 0; 226 227 build() { 228 Column() { 229 Son({reviewVotes:$reviewVotes}) 230 Button(`Father: ${this.reviewVotes}`) 231 ... 232 } 233 } 234 } 235 ``` 236 2372. Decorate **reviewVote** with \@Link in the child component **Son** to receive the value passed from **Father**. 238 239 ``` 240 @Component 241 struct Son{ 242 @Link reviewVotes: number; 243 build() { 244 Column() { 245 Grandson({reviewVotes:$reviewVotes}) 246 } 247 } 248 } 249 250 ``` 251 2523. Decorate **reviewVote** with \@Link in the grandchild component **GrandSon** to receive the value passed from **Son**. 253 254 ``` 255 @Component 256 struct Grandson{ 257 @Link reviewVotes: number; 258 259 build() { 260 Column() { 261 Button(`Grandson: ${this.reviewVotes}`) 262 ... 263 }.width('100%') 264 } 265 } 266 ``` 267 268 269## How is a callback function defined in JS? (API version 9) 270 271**Solution** 272 273The following is an example to illustrate how to define a callback function: 274 2751. Define the callback function. 276 277 ``` 278 // Define a callback function that contains two parameters and returns void. 279 myCallback: (a:number,b:string) => void 280 ``` 281 2822. Initialize the callback function by assigning values. 283 284 ``` 285 aboutToAppear() { 286 // Initialize the callback function. 287 this.myCallback= (a,b)=>{ 288 console.info(`handle myCallback a=${a},b=${b}`) 289 }} 290 ``` 291 292 293## How do I maximize performance in cases when a component needs to be updated multiple times? (API version 9) 294 295**Solution** 296 297Use the state management module for the purpose. Currently, the minimum update is supported. When the data dependency changes, instead of updating the entire custom component, only the view content that depends on the data is updated. 298 299 300## How does this of a function in an object point to the outer layer? (API version 9) 301 302**Solution** 303 304You can use the arrow function for this purpose. 305 306**Example** 307 308``` 309const obj = { 310 start:() => { 311 return this.num 312 } 313} 314``` 315 316 317## How do I obtain data through an API before page loading? (API version 9) 318 319**Symptom** 320 321Data needs to be obtained before page rendering so that the page can be rendered in time when needed. 322 323**Solution** 324 325In the **aboutToAppear** function, use an asynchronous API to obtain page data. After the data is obtained, the page is automatically refreshed with the \@State decorated variable. 326 327**Example** 328 329``` 330@Entry 331@Component 332struct Test6Page { 333 // After the data is obtained, the page is automatically refreshed. 334 @State message: string = 'loading.....' 335 aboutToAppear(){ 336 // Simulate an asynchronous API to obtain data. 337 setTimeout(()=>{ 338 this.message = 'new msg' 339 },3000) 340 } 341 build() { 342 Row() { 343 Column() { 344 Text(this.message) 345 .fontSize(50) 346 .fontWeight(FontWeight.Bold) 347 } 348 .width('100%') 349 } 350 .height('100%') 351 } 352} 353``` 354 355 356## How do I display sensor data in the Text component on the UI? (API version 9) 357 358**Solution** 359 360The type of data returned by the sensor is double. To display it in the Text component, first convert the data from double to string. 361 362 363## How do I listen for screen rotation events? (API version 9) 364 365**Solution** 366 367To listen for screen rotation events, use the **mediaquery** API. 368 369``` 370import mediaquery from '@ohos.mediaquery' 371let listener = mediaquery.matchMediaSync('(orientation: landscape)'); // Listen for landscape events. 372function onPortrait(mediaQueryResult) { 373 if (mediaQueryResult.matches) { 374 // do something here 375 } else { 376 // do something here 377 } 378} 379listener.on('change', onPortrait) // Register a callback. 380listener.off('change', onPortrait) // Deregister a callback. 381``` 382 383**Reference** 384 385[Media Query](../reference/apis-arkui/js-apis-mediaquery.md) 386 387 388## What should I do if a singleton does not take effect after the page is changed? (API version 9) 389 390**Symptom** 391 392A singleton works only in the same page. It becomes **undefined** when the page changes. 393 394**Solution** 395 396A JS file is generated for each page, and a defined singleton is generated in each JS file. Therefore, the singleton in applicable only to the owning page. 397 398To share an instance across pages, it must be created at the UIAbility or application level. 399 400 401## How do I convert a string in time format to a Date object? (API version 9) 402 403**Solution** 404 405If the string is in the yyyy-MM-dd format, you can convert it to a Date object by calling **new Date("yyyy-MM-dd"\)**. 406 407``` 408new Date("2021-05-23"); 409new Date("2020/2/29"); 410new Date("2020-14-03"); 411new Date("14-02-2021"); 412``` 413 414If the string is in any other format, you can convert it to a Date object by calling **new Date(year:number,month:number,day?:number,hour?:number,minute?:number,second?:number,ms?:number)**. 415 416``` 417// Syntax for creating a date based on parameters: 418new Date(yearValue, IndexOfMonth, dayValue, hours, minutes, seconds) 419``` 420 421Pass the date parameters as arguments. 422 423- **yearValue**: the year in the ISO 8061 YYYY format, for example, **2021**. If we specify a value in YY format, it may be incorrectly accepted. For example, the value **21** would be regarded as the year 1921 rather than 2021. 424 425- **IndexOfMonth**: index of the month, which starts from 0. It is obtained by subtracting 1 from the month value. For example, for March, the month value is 3, but the value of **IndexOfMonth** will be 2 (that is, 3 – 1 = 2). The value should typically be within the 0–11 range. 426 427- **dayValue**: day of the month. It should range from 1 to 31 depending on the number of days in the month. For example, for 21-05-2021, the day value is **21**. 428 429- **hours**: hour of the day. For example, **10** for 10 o'clock. 430 431- **minutes**: number of minutes that have elapsed in the hour. 432 433- **seconds**: number of seconds past a minute. 434 435 436## How do I convert a string to a byte array in ArkTS? (API version 9) 437 438**Solution** 439 440Refer to the following code: 441 442``` 443stringToArray(str:string) { 444 var arr = []; 445 for(var i = 0,j = str.length;i<j;++i) { 446 arr.push(str.charCodeAt(i)) 447 } 448 return arr; 449} 450``` 451 452 453## How do I implement string encoding and decoding in ArkTS? (API version 9) 454 455**Solution** 456 457You can use **TextEncoder** and **TextDecoder** provided by the **util** module. 458 459**Reference** 460 461[TextEncoder](../reference/apis-arkts/js-apis-util.md#textencoder), [TextDecoder](../reference/apis-arkts/js-apis-util.md#textdecoder) 462 463 464## How do I import and export namespaces? (API version 9) 465 466**Solution** 467 468Use **import** and **export** statements. 469 470- Exporting namespaces from the database: 471 472 ``` 473 namespace Util{ 474 export function getTime(){ 475 return Date.now() 476 } 477 } 478 export default Util 479 ``` 480 481- Importing namespaces 482 483 ``` 484 import Util from './util' 485 Util.getTime() 486 ``` 487 488 489## Can relational database operations be performed in the Worker thread? (API version 9) 490 491Currently, the relational database (RDB) object in the UI main thread cannot be sent to the Worker thread for operations. To use the RDB in the Worker thread, you must obtain a new RDB object. 492 493 494## How do I obtain files in the resource directory of an application? (API version 9) 495 496**Solution** 497 498- Method 1: Use **$r** or **$rawfile**. This method applies to static access, during which the **resource** directory remains unchanged when the application is running. 499 500- Method 2: Use **ResourceManager**. This method applies to dynamic access, during which the **resource** directory dynamically changes when the application is running. 501 502**Reference** 503 504[Resource Categories and Access](../quick-start/resource-categories-and-access.md) and [@ohos.resourceManager (Resource Management)](../reference/apis-localization-kit/js-apis-resource-manager.md) 505 506 507## How do I convert data from XML to JSON? (API version 9) 508 509**Symptom** 510 511The data returned by the server is encoded using Base64 in XML format and needs to be converted to the JSON format for subsequent processing. 512 513**Solution** 514 515Use the Base64-related APIs in the **util** module to decode data, and then use the **convertxml** module to parse data in XML format. 516 517**Example** 518 519``` 520import convertxml from '@ohos.convertxml'; 521import util from '@ohos.util'; 522 523@Entry 524@Component 525struct Faq_4_31 { 526 @State message: string = 'base64 to JSON' 527 528 build() { 529 Row() { 530 Column() { 531 Text(this.message) 532 .fontSize(50) 533 .fontWeight(FontWeight.Bold) 534 .onClick(() => { 535 / *Original data in GBK encoding 536 <?xml version="1.0" encoding="GBK"?> 537 <data> 538 <asset_no>xxxxx</asset_no> 539 <machine_sn>xxxx</machine_sn> 540 <bios_id>xxxx</bios_id> 541 <responsible_emp_name><![CDATA[xxxx]]></responsible_emp_name> 542 <responsible_account><![CDATA[xxxx xxxx]]></responsible_account> 543 <responsible_emp_no>xxxx</responsible_emp_no> 544 <responsible_dept><![CDATA[xxxx]]></responsible_dept> 545 <user_dept><![CDATA[xxxx]]></user_dept> 546 <user_name><![CDATA[xxx]]></user_name> 547 <cur_domain_account>xxxx</cur_domain_account> 548 <asset_loc><![CDATA[--]]></asset_loc> 549 <asset_loc_cur><![CDATA[]]></asset_loc_cur> 550 <asset_type>1</asset_type> 551 <asset_use>For Outsourcing Staff/xxxx</asset_use> 552 <overdue_date></overdue_date> 553 <asset_status>xxxx</asset_status> 554 <asset_period>xxxx</asset_period> 555 <license></license> 556 </data> 557 */ 558 let src = 'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iR0JLIj8+CjxkYXRhPgo8YXNzZXRfbm8+eHh4eHg8L2Fzc2V0X25vPgo8bWFjaGluZV9zbj54eHh4PC9tYWNoaW5lX3NuPgo8Ymlvc19pZD54eHh4PC9iaW9zX2lkPgo8cmVzcG9uc2libGVfZW1wX25hbWU+PCFbQ0RBVEFbeHh4eF1dPjwvcmVzcG9uc2libGVfZW1wX25hbWU+CjxyZXNwb25zaWJsZV9hY2NvdW50PjwhW0NEQVRBW3h4eHggeHh4eF1dPjwvcmVzcG9uc2libGVfYWNjb3VudD4KPHJlc3BvbnNpYmxlX2VtcF9ubz54eHh4PC9yZXNwb25zaWJsZV9lbXBfbm8+CjxyZXNwb25zaWJsZV9kZXB0PjwhW0NEQVRBW3h4eHhdXT48L3Jlc3BvbnNpYmxlX2RlcHQ+Cjx1c2VyX2RlcHQ+PCFbQ0RBVEFbeHh4eF1dPjwvdXNlcl9kZXB0Pgo8dXNlcl9uYW1lPjwhW0NEQVRBW3h4eF1dPjwvdXNlcl9uYW1lPgo8Y3VyX2RvbWFpbl9hY2NvdW50Pnh4eHg8L2N1cl9kb21haW5fYWNjb3VudD4KPGFzc2V0X2xvYz48IVtDREFUQVstLV1dPjwvYXNzZXRfbG9jPgo8YXNzZXRfbG9jX2N1cj48IVtDREFUQVtdXT48L2Fzc2V0X2xvY19jdXI+Cjxhc3NldF90eXBlPjE8L2Fzc2V0X3R5cGU+Cjxhc3NldF91c2U+Rm9yIE91dHNvdXJjaW5nIFN0YWZmL3h4eHg8L2Fzc2V0X3VzZT4KPG92ZXJkdWVfZGF0ZT48L292ZXJkdWVfZGF0ZT4KPGFzc2V0X3N0YXR1cz54eHh4PC9hc3NldF9zdGF0dXM+Cjxhc3NldF9wZXJpb2Q+eHh4eDwvYXNzZXRfcGVyaW9kPgo8bGljZW5zZT48L2xpY2Vuc2U+CjwvZGF0YT4=' 559 let base64 = new util.Base64Helper(); 560 // base64 decoding 561 let src_uint8Array = base64.decodeSync(src); 562 // Decode the string into a UTF-8 string. 563 let textDecoder = util.TextDecoder.create("utf-8",{ignoreBOM: true}) 564 let src_str = textDecoder.decodeWithStream(src_uint8Array) 565 // Replace the encoding field. 566 src_str = src_str.replace("GBK","utf-8") 567 console.log('Test src_str: ' + JSON.stringify(src_str)); 568 //Convert XML format to JSON format. 569 let conv = new convertxml.ConvertXML(); 570 let options = {trim : false, declarationKey:"_declaration", 571 instructionKey : "_instruction", attributesKey : "_attributes", 572 textKey : "_text", cdataKey:"_cdata", doctypeKey : "_doctype", 573 commentKey : "_comment", parentKey : "_parent", typeKey : "_type", 574 nameKey : "_name", elementsKey : "_elements"} 575 let src_json = JSON.stringify(conv.convertToJSObject(src_str, options)); 576 console.log('Test json: ' + JSON.stringify(src_json)); 577 }) 578 } 579 .width('100%') 580 } 581 .height('100%') 582 } 583} 584``` 585 586 587## What are the restrictions on using generator functions in TypeScript? (API version 9) 588 589**Solution** 590 591Below are the restrictions on using generator functions in TypeScript: 592 593- Expressions can be used only in strings (in the ${expression} format), **if** statements, **ForEach** parameters, and component parameters. 594 595- No expressions should cause any application state variables (including those decorated by \@State, \@Link, and \@Prop) to change. Otherwise, undefined and potentially unstable framework behavior may occur. 596 597- The generator function cannot contain local variables. 598 599None of the above restrictions apply to anonymous function implementations of event handlers (such as **onClick**). 600 601 602## How do I set a badge for each of the four corners of an image? (API version 9) 603 604**Symptom** 605 606 607 608**Solution** 609 610You can use absolute positioning to set the offset of the element anchor relative to the top start point of the parent container. In the layout container, setting this attribute does not affect the layout of the parent container. 611 612**Example** 613 614``` 615@Entry 616@Component 617struct PositionExample2 { 618 build() { 619 Column({ space: 20 }) { 620 Stack({ alignContent: Alignment.TopStart }) { 621 Row() 622 .size({ width: '100', height: '100' }) 623 .backgroundColor(0xdeb887) 624 Image($r('app.media.app_icon')) 625 .size({ width: 25, height: 25 }) 626 .markAnchor({ x: 0, y: 0 }) 627 Image($r('app.media.app_icon')) 628 .size({ width: 25, height: 25 }) 629 .markAnchor({ x: 25, y: 25 }) 630 .position({ x: '100%', y: '100%' }) 631 }.margin({ top: 25 }).width('100').height('100') 632 } 633 .width('100%').margin({ top: 25 }) 634 } 635} 636``` 637 638 639## How do I use the util.generateRandomUUID parameter? (API version 9) 640 641**Solution** 642 643The **generateRandomUUID** API is based on the Node.js function **crypto.randomUUID()**. If the parameter passed in is **false**, a new UUID is generated and cached in the system. If the parameter passed in is **true**, a cached UUID is used. 644 645**Reference** 646 647[util.generateRandomUUID](../reference/apis-arkts/js-apis-util.md#utilgeneraterandomuuid9) 648 649 650## Do the Worker thread and the main thread run in the same global context? (API version 9) 651 652**Solution** 653 654No. The Worker thread and the main thread are not in the same context. They interact with each other in data communication mode. 655 656**Reference** 657 658[@ohos.worker (Starting the Worker)](../reference/apis-arkts/js-apis-worker.md) 659 660 661## How do I set one application icon for different device types? (API version 9) 662 663**Symptom** 664 665 666 667**Solution** 668 669To configure your application icon to show on different device types, use resource qualifiers. 670 671**Example** 672 6731. Create a resource directory and add resource files to the directory. In this example, a **tablet** resource directory is created in **src/main/resources** and a **media** resource folder in the **tablet** directory. 674 675``` 676├─base 677│ ├─element 678│ ├─media 679│ └─profile 680├─rawfile 681├─tablet 682│ ├─element 683│ └─media 684``` 685 6862. Add the icon file to be displayed when the device type is tablet to the **media** folder. Reference the icon file on the UI. 687 688``` 689@Entry @Component struct Index { build() { 690 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 691 Text($r("app.string.my_string")) 692 .fontSize($r("app.float.my_float")) 693 .fontColor($r("app.color.my_color")) 694 Image($r("app.media.my_image")) 695 .width(100) 696 .height(100) 697 } 698 .width('100%') 699 .height('100%') } } 700``` 701 702**Reference** 703 704 705 706 707## How do I prevent this in a method from changing to 'undefined' when the method is called? (API version 9) 708 709**Symptom** 710 711 712 713**Solution** 714 715Method 1: Add **.bind(this)** when calling the method. 716 717Method 2: Use the arrow function. 718 719 720## How does the systemTime.getCurrentTime() API differ from the new Date().getTime() API of JS? (API version 9) 721 722**Solution** 723 724**systemTime.getCurrentTime(false)** is equivalent to **new Date().getTime()**, returning the number of milliseconds since January 1, 1970. **systemTime.getCurrentTime(true)** returns the number of nanoseconds since January 1, 1970. The system time is used in both APIs. 725 726 727## How do I implement the ArkTS counterpart of the JS slot feature? (API version 9) 728 729**Solution** 730 731Use @Build and @BuilderParam in ArkTS. 732 733**Reference** 734 735[@BuilderParam Decorator: @Builder Function Reference](../quick-start/arkts-builderparam.md) 736 737 738## Why is text not centered vertically when lineHeight is set? (API version 9) 739 740**Cause** 741 742Text in the **Text** component is centered by default. You do not need to set the **lineHeight** attribute. As the text is drawn from the bottom, an appropriate line height can have the text centered. However, if the line height is too large, the text appears aligned toward the bottom. In general cases, use the **lineHeight** attribute together with the **padding** attribute to adjust the line spacing. 743 744**Reference** 745 746[Text](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#example-1) 747 748 749## Which API is used for URL encoding? (API version 9) 750 751**Solution** 752 753Use the global function **encodeURI** for encoding and **decodeURI** for decoding. For example, the space character ""is encoded as %20. 754 755``` 756let a = encodeURI(" ") 757console.log(a) // %20 758``` 759 760 761## How do I parse XML files? (API version 9) 762 763**Solution** 764 765You can use the **convert** API of the **ConvertXML** module to parse XML text into JS objects. 766 767**Reference** 768 769[@ohos.convertxml (XML-to-JavaScript Conversion)](../reference/apis-arkts/js-apis-convertxml.md) 770 771 772## What should I do if the .stateStyles doesn't conform standard error is reported with the use of the @Styles decorator? (API version 9) 773 774**Cause** 775 776The @Styles decorator is used for non-universal attributes. 777 778**Solution** 779 780Use the @Styles decorator only for non-universal attributes. Alternatively, use Builder to extract common components. 781 782 783## When do I use $$ for the \<Radio> component? (API version 9) 784 785**Solution** 786 787You can use **$$** for two-way binding of a variable for the **Radio** component. In this way, changes to the variable trigger re-render of only the owning component, improving the rendering speed. 788 789When the state of the **Radio** component changes, the bound variable is not automatically updated. 790 791**Reference** 792 793[$$ Syntax: Two-Way Synchronization of Built-in Components](../quick-start/arkts-two-way-sync.md) 794 795## What should I do if ForEach does not work on a real device? 796 797**Symptom** 798 799**ForEach** works in the previewer, but not on a real device. 800 801**Cause** 802 803If the system version on the real device is 3.2 beta5 or later, the minimum update policy is enabled by default. 804 805However, minimum update is not enabled in DevEco Studio of an earlier version. As a result, components run abnormally. 806 807**Solution** 808 809Add the **metadata** configuration item to the **module.json5** file. 810 811``` 812{ 813 "module": { 814 "metadata": [ 815 { 816 "name": "ArkTSPartialUpdate", 817 "value": "true" 818 } ] 819 } 820} 821``` 822 823## Does AppStorage allow for object sharing between threads? If not, what's the workaround? (API version 10) 824 825**Solution** 826 827AppStorage provides central storage for application UI state attributes. It is bound to the application process and is created by the UI framework at application startup. 828 829AppStorage supports state sharing among multiple UIAbility instances in the main thread of an application. 830 831As AppStorage must run on the UI thread, it does not allow for object sharing with other threads. Currently, no workaround is available. 832 833**Reference** 834 835[AppStorage: Application-wide UI State Storage](../quick-start/arkts-appstorage.md) 836 837## How do I register custom fonts? Where can I find the recommended font resources? How do I obtain them? (API version 10) 838 839**Solution** 840 841Store your custom resource files in the project directory. In the code, call **registerFont** to register a custom font. The registered font can then be used for text components through the **fontFamily** attribute. 842To reference custom font resources, the $rawfile mode is recommended. The resources can be stored in the **resources/rawfile** directory. 843 844**Reference** 845 846[@ohos.font (Custom Font Registration)](../reference/apis-arkui/js-apis-font.md) 847 848## How does the Text component load Unicode characters? (API version 10) 849 850**Solution** 851 852Pass a string to the **content** parameter of the **Text** component, with Unicode escape sequence in the string. The sample code is as follows: 853 854```ts 855@Entry 856@Component 857struct text { 858 build() { 859 Column(){ 860 Text("\u{1F468}\u200D\u{1F468}\u200D\u{1F467}\u200D\u{1F466}") 861 .width(100) 862 .height(100) 863 .fontSize(50) 864 } 865 } 866} 867``` 868 869## How do I implement the ArkTS counterpart of the JS slot feature? (API version 10) 870 871**Solution** 872 873ArkUI provides a more lightweight mechanism for reusing UI elements: \@Builder. An \@Builder decorated function is a special function that serves similar purposes as the **build** function. The \@Builder decorated function follows the same syntax rules as the **build()** function. You can abstract reusable UI elements into a method and call the method in **build**. 874ArkUI also provides @BuilderParam, a decorator used to decorate a custom component variable of type Reference to an \@Builder method. When initializing a custom component, you can add the specific feature to it by assigning a value to the variable. This decorator can be used to declare an element of any UI description, similar to a slot placeholder. 875 876 877**Reference** 878 8791. [@Builder Decorator: Custom Builder Function](../quick-start/arkts-builder.md) 8802. [@BuilderParam Decorator: @Builder Function Reference](../quick-start/arkts-builderparam.md) 881