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 assigning 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 assigning 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 60 61To listen for object changes in an array, use the @Observed and @ObjectLink decorators. **@Observed** applies to classes, and **@ObjectLink** applies to variables. 62 63**Example** 64 651. Use @Observed on a class. 66 67 ``` 68 @Observed 69 class ClassA { 70 public name: string 71 public c: number 72 public id: number 73 74 constructor(c: number, name: string = 'OK') { 75 this.name = name 76 this.c = c 77 } 78 } 79 ``` 80 812. Use @ObjectLink on a component variable. 82 83 ``` 84 @Component 85 struct ViewA { 86 label: string = 'ViewA1' 87 @ObjectLink a: ClassA 88 89 build() { 90 Row() { 91 Button(`ViewA [${this.label}] this.a.c= ${this.a.c} +1`) 92 .onClick(() => { 93 this.a.c += 1 94 }) 95 }.margin({ top: 10 }) 96 } 97 } 98 ``` 99 100 101**Reference** 102 103[\@Observed and \@ObjectLink: Observing Attribute Changes in Nested Class Objects](../quick-start/arkts-observed-and-objectlink.md) 104 105 106## How do I transfer values through the parent component to @Link decorated varaibles in a child component? (API version 9) 107 108**Solution** 109 110To 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. 111 112**Example** 113 114The **@Link** semantics are derived from the '**$**' operator. In other words, **\$isPlaying** is the 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. 115 1161. Use the @State decorator in the parent component and use the '**\$**' operator to create a reference for transferring data. 117 118 ``` 119 @Entry 120 @Component 121 struct Player { 122 @State isPlaying: boolean = false 123 build() { 124 Column() { 125 PlayButton({ buttonPlaying: $isPlaying }) 126 Text(`Player is ${this.isPlaying ? '' : 'not'} playing`).fontSize(18) 127 Button('Parent:' + this.isPlaying) 128 .margin(15) 129 .onClick(() => { 130 this.isPlaying = !this.isPlaying 131 }) 132 } 133 } 134 } 135 136 137 ``` 138 1392. Use @Link in the child component to receive data. 140 141 ``` 142 @Component 143 struct PlayButton { 144 @Link buttonPlaying: boolean 145 146 build() { 147 Column() { 148 Button(this.buttonPlaying ? 'pause' : 'play') 149 .margin(20) 150 .onClick(() => { 151 this.buttonPlaying = !this.buttonPlaying 152 }) 153 } 154 } 155 } 156 ``` 157 158 159**Reference** 160 161[@Link](../quick-start/arkts-link.md) 162 163## How does a component synchronize state with its grandchild components? 164 165**Solution** 166 167- 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. 168 169- 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). 170 171**Example 1** 172 1731. Include a child component in the component. Employ @Provide in the component to provide the **reviewVote** parameter to its grandchild component. 174 175 ``` 176 @Entry 177 @Component 178 struct Father{ 179 @Provide("reviewVote") reviewVotes: number = 0; 180 181 build() { 182 Column() { 183 Son() 184 Button(`Father: ${this.reviewVotes}`) 185 ... 186 } 187 } 188 } 189 ``` 190 1912. Include the grandchild component in the child component. 192 193 ``` 194 @Component 195 struct Son{ 196 build() { 197 Column() { 198 GrandSon() 199 } 200 } 201 } 202 ``` 203 2043. Employ @Consume in the grandchild component to receive the **reviewVote** parameter. 205 206 ``` 207 @Component 208 struct GrandSon{ 209 @Consume("reviewVote") reviewVotes: number 210 211 build() { 212 Column() { 213 Button(`GrandSon: ${this.reviewVotes}`) 214 ... 215 }.width('100%') 216 } 217 } 218 ``` 219 220 221**Example 2** 222 2231. Employ @State in the component **Father** to decorate **reviewVote**. 224 225 ``` 226 @Entry 227 @Component 228 struct Father { 229 @State reviewVotes: number = 0; 230 231 build() { 232 Column() { 233 Son({reviewVotes:$reviewVotes}) 234 Button(`Father: ${this.reviewVotes}`) 235 ... 236 } 237 } 238 } 239 ``` 240 2412. Employ @Link in the child component **Son** to receive the **reviewVote** parameter passed from **Father**. 242 243 ``` 244 @Component 245 struct Son{ 246 @Link reviewVotes: number; 247 build() { 248 Column() { 249 Grandson({reviewVotes:$reviewVotes}) 250 } 251 } 252 } 253 254 255 ``` 256 2573. Employ @Link in the grandchild component **GrandSon** to receive the **reviewVote** parameter passed from **Son**. 258 259 ``` 260 @Component 261 struct Grandson{ 262 @Link reviewVotes: number; 263 264 build() { 265 Column() { 266 Button(`Grandson: ${this.reviewVotes}`) 267 ... 268 }.width('100%') 269 } 270 } 271 ``` 272 273 274## How is a callback function defined in JS? (API version 9) 275 276**Solution** 277 278The following is an example to illustrate how to define a callback function: 279 2801. Define the callback function. 281 282 ``` 283 // Define a callback function that contains two parameters and returns void. 284 myCallback: (a:number,b:string) => void 285 ``` 286 2872. Initialize the callback function by assigning values. 288 289 ``` 290 aboutToAppear() { 291 // Initialize the callback function. 292 this.myCallback= (a,b)=>{ 293 console.info(`handle myCallback a=${a},b=${b}`) 294 }} 295 ``` 296 297 298## How do I maximize performance in cases when a component needs to be updated for multiple times? (API version 9) 299 300**Solution** 301 302Use 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. 303 304## How does this of a function in an object point to the outer layer? (API version 9) 305 306**Solution** 307 308You can use the arrow function for this purpose. 309 310**Example** 311 312``` 313const obj = { 314 start:() => { 315 return this.num 316 } 317} 318``` 319 320## How do I obtain data through an API before page loading? (API version 9) 321 322**Symptom** 323 324Data needs to be obtained before page rendering so as to be rendered when needed. 325 326**Solution** 327 328In the **aboutToAppear** function, use an asynchronous API to obtain page data and @State to decorate related variables. After the data is obtained, the page is automatically refreshed based on the variables. 329 330**Example** 331 332``` 333@Entry 334@Component 335struct Test6Page { 336 // After the data is obtained, the page is automatically refreshed. 337 @State message: string = 'loading.....' 338 aboutToAppear(){ 339 // Simulate an asynchronous API to obtain data. 340 setTimeout(()=>{ 341 this.message = 'new msg' 342 },3000) 343 } 344 build() { 345 Row() { 346 Column() { 347 Text(this.message) 348 .fontSize(50) 349 .fontWeight(FontWeight.Bold) 350 } 351 .width('100%') 352 } 353 .height('100%') 354 } 355} 356``` 357 358## How do I display sensor data in the \<Text> component on the UI in real time? (API version 9) 359 360**Solution** 361 362The type of data returned by the sensor is double. To display it in the \<Text> component, first convert the data from double to string. 363 364## How do I listen for screen rotation events? (API version 9) 365 366**Solution** 367 368To listen for screen rotation events, use the **mediaquery** API. 369 370``` 371import mediaquery from '@ohos.mediaquery' 372let listener = mediaquery.matchMediaSync('(orientation: landscape)'); // Listen for landscape events. 373function onPortrait(mediaQueryResult) { 374 if (mediaQueryResult.matches) { 375 // do something here 376 } else { 377 // do something here 378 } 379} 380listener.on('change', onPortrait) // Register a callback. 381listener.off('change', onPortrait) // Deregister a callback. 382``` 383 384**Reference** 385 386[@ohos.mediaquery (Media Query)](../reference/apis/js-apis-mediaquery.md) 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## How do I convert a string in time format to a date object? (API version 9) 401 402**Solution** 403 404If the string is in the yyyy-MM-dd format, you can convert it to a date object by calling **new Date\("yyyy-MM-dd"\)**. 405 406``` 407new Date("2021-05-23"); 408new Date("2020/2/29"); 409new Date("2020-14-03"); 410new Date("14-02-2021"); 411``` 412 413If the string is in other formats, 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\)**. 414 415``` 416// Syntax for creating a date based on parameters: 417new Date(yearValue, IndexOfMonth, dayValue, hours, minutes, seconds) 418``` 419 420Pass the date parameters as arguments. 421 422- **yearValue**: the year in the ISO 8061 YYYY format, for example, **2021**. If we specify a value in YY format, it will be incorrectly accepted. For example, the value **21** would be considered the year 1921 rather than 2021. 423- **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. 424- **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**. 425- **hours**: hour of the day. For example, **10** for 10 o'clock. 426- **minutes**: number of minutes that have elapsed in the hour. 427- **seconds**: number of seconds past a minute. 428 429## How do I convert a string to a byte array in ArkTS? (API version 9) 430 431**Solution** 432 433Refer to the following code: 434 435``` 436stringToArray(str:string) { 437 var arr = []; 438 for(var i = 0,j = str.length;i<j;++i) { 439 arr.push(str.charCodeAt(i)) 440 } 441 return arr; 442} 443``` 444 445## How do I implement string encoding and decoding in ArkTS? (API version 9) 446 447**Solution** 448 449You can use **TextEncoder** and **TextDecoder** provided by the **util** module. 450 451**Reference** 452 453[TextEncoder](../reference/apis/js-apis-util.md#textencoder), [TextDecoder](../reference/apis/js-apis-util.md#textdecoder) 454 455## How do I import and export namespaces? (API version 9) 456 457**Solution** 458 459Use **import** and **export** statements. 460 461- Exporting namespaces from the database: 462 463 ``` 464 namespace Util{ 465 export function getTime(){ 466 return Date.now() 467 } 468 } 469 export default Util 470 ``` 471 472- Importing namespaces 473 474 ``` 475 import Util from './util' 476 Util.getTime() 477 ``` 478 479## Can relational database operations be performed in the Worker thread? (API version 9) 480 481Currently, 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. 482 483## How do I obtain files in the resource directory of an application? (API version 9) 484 485**Solution** 486 487- Method 1: Use **\$r** or **\$rawfile**. This method applies to static access, during which the **resource** directory remains unchanged when the application is running. 488- Method 2: Use **ResourceManager**. This method applies to dynamic access, during which the **resource** directory dynamically changes when the application is running. 489 490**Reference** 491 492[Resource Categories and Access](../quick-start/resource-categories-and-access.md) and [@ohos.resourceManager (Resource Manager)](../reference/apis/js-apis-resource-manager.md) 493 494## How do I convert the XML format to the JSON format? (API version 9) 495 496**Symptom** 497 498The data returned by the server is encoded using Base64 in XML format and needs to be converted to the JSON format for subsequent processing. 499 500**Solution** 501 502Use the Base64-related APIs in the **util** module to decode data, and then use the **convertxml** module to parse data in XML format. 503 504**Example** 505 506``` 507import convertxml from '@ohos.convertxml'; 508import util from '@ohos.util'; 509 510@Entry 511@Component 512struct Faq_4_31 { 513 @State message: string = 'base64 to JSON' 514 515 build() { 516 Row() { 517 Column() { 518 Text(this.message) 519 .fontSize(50) 520 .fontWeight(FontWeight.Bold) 521 .onClick(() => { 522 / *Original data in GBK encoding 523 <?xml version="1.0" encoding="GBK"?> 524 <data> 525 <asset_no>xxxxx</asset_no> 526 <machine_sn>xxxx</machine_sn> 527 <bios_id>xxxx</bios_id> 528 <responsible_emp_name><![CDATA[xxxx]]></responsible_emp_name> 529 <responsible_account><![CDATA[xxxx xxxx]]></responsible_account> 530 <responsible_emp_no>xxxx</responsible_emp_no> 531 <responsible_dept><![CDATA[xxxx]]></responsible_dept> 532 <user_dept><![CDATA[xxxx]]></user_dept> 533 <user_name><![CDATA[xxx]]></user_name> 534 <cur_domain_account>xxxx</cur_domain_account> 535 <asset_loc><![CDATA[--]]></asset_loc> 536 <asset_loc_cur><![CDATA[]]></asset_loc_cur> 537 <asset_type>1</asset_type> 538 <asset_use>For Outsourcing Staff/xxxx</asset_use> 539 <overdue_date></overdue_date> 540 <asset_status>xxxx</asset_status> 541 <asset_period>xxxx</asset_period> 542 <license></license> 543 </data> 544 */ 545 let src = 'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iR0JLIj8+CjxkYXRhPgo8YXNzZXRfbm8+eHh4eHg8L2Fzc2V0X25vPgo8bWFjaGluZV9zbj54eHh4PC9tYWNoaW5lX3NuPgo8Ymlvc19pZD54eHh4PC9iaW9zX2lkPgo8cmVzcG9uc2libGVfZW1wX25hbWU+PCFbQ0RBVEFbeHh4eF1dPjwvcmVzcG9uc2libGVfZW1wX25hbWU+CjxyZXNwb25zaWJsZV9hY2NvdW50PjwhW0NEQVRBW3h4eHggeHh4eF1dPjwvcmVzcG9uc2libGVfYWNjb3VudD4KPHJlc3BvbnNpYmxlX2VtcF9ubz54eHh4PC9yZXNwb25zaWJsZV9lbXBfbm8+CjxyZXNwb25zaWJsZV9kZXB0PjwhW0NEQVRBW3h4eHhdXT48L3Jlc3BvbnNpYmxlX2RlcHQ+Cjx1c2VyX2RlcHQ+PCFbQ0RBVEFbeHh4eF1dPjwvdXNlcl9kZXB0Pgo8dXNlcl9uYW1lPjwhW0NEQVRBW3h4eF1dPjwvdXNlcl9uYW1lPgo8Y3VyX2RvbWFpbl9hY2NvdW50Pnh4eHg8L2N1cl9kb21haW5fYWNjb3VudD4KPGFzc2V0X2xvYz48IVtDREFUQVstLV1dPjwvYXNzZXRfbG9jPgo8YXNzZXRfbG9jX2N1cj48IVtDREFUQVtdXT48L2Fzc2V0X2xvY19jdXI+Cjxhc3NldF90eXBlPjE8L2Fzc2V0X3R5cGU+Cjxhc3NldF91c2U+Rm9yIE91dHNvdXJjaW5nIFN0YWZmL3h4eHg8L2Fzc2V0X3VzZT4KPG92ZXJkdWVfZGF0ZT48L292ZXJkdWVfZGF0ZT4KPGFzc2V0X3N0YXR1cz54eHh4PC9hc3NldF9zdGF0dXM+Cjxhc3NldF9wZXJpb2Q+eHh4eDwvYXNzZXRfcGVyaW9kPgo8bGljZW5zZT48L2xpY2Vuc2U+CjwvZGF0YT4=' 546 let base64 = new util.Base64Helper(); 547 // base64 decoding 548 let src_uint8Array = base64.decodeSync(src); 549 // Decode the string into a UTF-8 string. 550 let textDecoder = util.TextDecoder.create("utf-8",{ignoreBOM: true}) 551 let src_str = textDecoder.decodeWithStream(src_uint8Array) 552 // Replace the encoding field. 553 src_str = src_str.replace("GBK","utf-8") 554 console.log('Test src_str: ' + JSON.stringify(src_str)); 555 //Convert XML format to JSON format. 556 let conv = new convertxml.ConvertXML(); 557 let options = {trim : false, declarationKey:"_declaration", 558 instructionKey : "_instruction", attributesKey : "_attributes", 559 textKey : "_text", cdataKey:"_cdata", doctypeKey : "_doctype", 560 commentKey : "_comment", parentKey : "_parent", typeKey : "_type", 561 nameKey : "_name", elementsKey : "_elements"} 562 let src_json = JSON.stringify(conv.convertToJSObject(src_str, options)); 563 console.log('Test json: ' + JSON.stringify(src_json)); 564 }) 565 } 566 .width('100%') 567 } 568 .height('100%') 569 } 570} 571``` 572 573## What are the restrictions on using generator functions in TypeScript? (API version 9) 574 575**Solution** 576 577Below are the restrictions on using generator functions in TypeScript: 578 579- Expressions can be used only in character strings (in the \(\$\{expression\}\) format), **if** conditions, **ForEach** parameters, and component parameters. 580- No expressions should cause any application state variables (**@State**, **@Link**, and **@Prop**) to change. Otherwise, undefined and potentially unstable framework behavior may occur. 581- The generator function cannot contain local variables. 582 583None of the above restrictions apply to anonymous function implementations of event handlers (such as **onClick**). 584 585## How do I set a badge for each of the four corners of an image? (API version 9) 586 587**Solution** 588 589You 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. 590 591**Example** 592 593``` 594@Entry 595@Component 596struct PositionExample2 { 597 build() { 598 Column({ space: 20 }) { 599 Stack({ alignContent: Alignment.TopStart }) { 600 Row() 601 .size({ width: '100', height: '100' }) 602 .backgroundColor(0xdeb887) 603 Image($r('app.media.app_icon')) 604 .size({ width: 25, height: 25 }) 605 .markAnchor({ x: 0, y: 0 }) 606 Image($r('app.media.app_icon')) 607 .size({ width: 25, height: 25 }) 608 .markAnchor({ x: 25, y: 25 }) 609 .position({ x: '100%', y: '100%' }) 610 }.margin({ top: 25 }).width('100').height('100') 611 } 612 .width('100%').margin({ top: 25 }) 613 } 614} 615``` 616 617## How do I use the util.generateRandomUUID parameter? (API version 9) 618 619**Solution** 620 621The bottom layer of **generateRandomUUID** uses the **Node.js crypto.randomUUID\(\)** API. If the parameter passed in is **false**, a new UUID is generated and cached in the system. If the parameter passed in is **true**, the existing cached UUID is used. 622 623**Reference** 624 625[util.generateRandomUUID](../reference/apis/js-apis-util.md#utilgeneraterandomuuid9) 626 627## Do the Worker thread and the main thread run in the same global context? (API version 9) 628 629**Solution** 630 631No. The Worker thread and the main thread are not in the same context. They interact with each other in data communication mode. 632 633**Reference** 634 635[@ohos.worker (Worker Startup)](../reference/apis/js-apis-worker.md) 636 637## How do I set one application icon for different device types? (API version 9) 638 639**Solution** 640 641To configure your application icon to show on different device types, use resource qualifiers. 642 643**Example** 644 6451. 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. 646 647``` 648├─base 649│ ├─element 650│ ├─media 651│ └─profile 652├─rawfile 653├─tablet 654│ ├─element 655│ └─media 656``` 657 6582. Add the icon file to be displayed when the device type is tablet to the **media** folder. Reference the icon file on the UI. 659 660``` 661@Entry @Component struct Index { build() { 662 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 663 Text($r("app.string.my_string")) 664 .fontSize($r("app.float.my_float")) 665 .fontColor($r("app.color.my_color")) 666 Image($r("app.media.my_image")) 667 .width(100) 668 .height(100) 669 } 670 .width('100%') 671 .height('100%') } } 672``` 673 674## How do I prevent "this" in a method from changing to "undefined" when the method is called? (API version 9) 675 676**Solution** 677 678Method 1: Add **.bind\(this\)** when calling the method. 679 680Method 2: Use the arrow function. 681 682## Is there any difference between the systemTime.getCurrentTime\(\) API of OpenHarmony and the new Date\(\).getTime\(\) API of JS? (API version 9) 683 684**Solution** 685 686**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. 687 688## How do I implement the ArkTS counterpart of the JS slot feature? (API version 9) 689 690**Solution** 691 692Use @Build and @BuilderParam in ArkTS. 693 694**Reference** 695 696[\@BuilderParam: @Builder Function Reference](../quick-start/arkts-builderparam.md). 697 698## Why is the text not centered vertically when lineHeight is set? (API version 9) 699 700**Cause** 701 702Text 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. 703 704**Reference** 705 706[Text](../reference/arkui-ts/ts-basic-components-text.md#example-1) 707 708 709## Which API is used for URL encoding? (API version 9) 710 711**Solution** 712 713Use the global function **encodeURI** for encoding and **decodeURI** for decoding. For example, the space character ""is encoded as %20. 714 715``` 716let a = encodeURI(" ") 717console.log(a) // %20 718``` 719 720## How do I parse XML files? (API version 9) 721 722**Solution** 723 724You can use the **convert** API of the **ConvertXML** module to parse XML text into JS objects. 725 726**Reference** 727 728[@ohos.convertxml (XML-to-JavaScript Conversion)](../reference/apis/js-apis-convertxml.md) 729 730## What should I do if the .stateStyles doesn't conform standard error is reported with the use of the @Styles decorator? (API version 9) 731 732**Cause** 733 734The @Styles decorator is used for non-universal attributes. 735 736**Solution** 737 738Use the @Styles decorator only for non-universal attributes. Alternatively, use Builder to extract common components. 739 740## How do I use \$\$ for the \<Radio> component? (API version 9) 741 742**Solution** 743 744When the **\<Radio>** component uses a variable bound to **\$\$**, changes to the variable trigger re-render of only the owning component, improving the rendering speed. 745 746When the state of the **\<Radio>** component changes, the bound variable is not automatically updated. 747 748**Reference** 749 750[$ Syntax: Two-Way Synchronization of Built-in Components](../quick-start/arkts-two-way-sync.md) 751 752## What should I do if ForEach does not work on a real device? 753 754**Symptom** 755 756**ForEach** works in the previewer, but not on a real device. 757 758**Cause** 759 760If the system version on the real device is 3.2 beta5 or later, the minimum update policy is enabled by default. 761 762However, minimum update is not enabled in DevEco Studio of an earlier version. As a result, components run abnormally. 763 764**Solution** 765 766Add the **metadata** configuration item to the **module.json5** file. 767 768``` 769{ 770 "module": { 771 "metadata": [ 772 { 773 "name": "ArkTSPartialUpdate", 774 "value": "true" 775 } ] 776 } 777} 778``` 779