国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁 web前端 js教程 探索角度形式:訊號的新替代方案

探索角度形式:訊號的新替代方案

Nov 08, 2024 am 07:03 AM

Exploring Angular Forms: A New Alternative with Signals

探索角度形式:訊號的新替代方案

在 Angular 的世界中,無論您是在製作簡單的登入頁面還是更複雜的使用者設(shè)定檔介面,表單對於使用者互動都是至關(guān)重要的。 Angular 傳統(tǒng)上提供兩種主要方法:範(fàn)本驅(qū)動表單反應(yīng)式表單。在我之前的 Angular 反應(yīng)式表單系列中,我探索如何利用反應(yīng)式表單的強大功能來管理複雜邏輯、建立動態(tài)表單以及建立自訂表單控制項。

用於管理反應(yīng)性的新工具 - 訊號 - 已在 Angular 版本 16 中引入,此後一直是 Angular 維護人員關(guān)注的焦點,並在版本 17 中變得穩(wěn)定。訊號允許您處理狀態(tài)變更聲明性地,提供了一個令人興奮的替代方案,將範(fàn)本驅(qū)動表單的簡單性與反應(yīng)表單的強大反應(yīng)性結(jié)合起來。本文將研究訊號如何為 Angular 中的簡單和複雜形式添加反應(yīng)性。

回顧:角度形式方法

在深入探討使用訊號增強範(fàn)本驅(qū)動表單的主題之前,讓我們先快速回顧一下 Angular 的傳統(tǒng)表單方法:

  1. 模板驅(qū)動表單:使用 ngModel 等指令直接在 HTML 範(fàn)本中定義,這些表單易於設(shè)置,非常適合簡單表單。但是,它們可能無法提供更複雜場景所需的細微控制。

    這是範(fàn)本驅(qū)動表單的最小範(fàn)例:

    <form (ngSubmit)="onSubmit()">
      <label for="name">Name:</label>
      <input>
    
    </li>
    </ol>
    
    
    
    <pre class="brush:php;toolbar:false">```typescript
    import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html'
    })
    export class AppComponent {
      name = '';
    
      onSubmit() {
        console.log(this.name);
      }
    }
    ```
    
    1. 反應(yīng)式表單:使用 Angular 的 FormGroup、FormControl 和 FormArray 類別在元件類別中以程式設(shè)計方式進行管理;反應(yīng)式表單提供對表單狀態(tài)和驗證的精細控制。正如我之前關(guān)於 Angular Reactive Forms 的文章所討論的那樣,這種方法非常適合複雜的表單。

      這是一個反應(yīng)式形式的最小範(fàn)例:

      import { Component } from '@angular/core';
      import { FormGroup, FormControl } from '@angular/forms';
      
      @Component({
        selector: 'app-root',
        templateUrl: './app.component.html'
      })
      export class AppComponent {
        form = new FormGroup({
          name: new FormControl('')
        });
      
        onSubmit() {
          console.log(this.form.value);
        }
      }
      
    ```html
    <form [formGroup]="form" (ngSubmit)="onSubmit()">
      <label for="name">Name:</label>
      <input>
    
    
    
    <h2>
      
      
      Introducing Signals as a New Way to Handle Form Reactivity
    </h2>
    
    <p>With the release of Angular 16, signals have emerged as a new way to manage reactivity. Signals provide a declarative approach to state management, making your code more predictable and easier to understand. When applied to forms, signals can enhance the simplicity of template-driven forms while offering the reactivity and control typically associated with reactive forms.</p>
    
    <p>Let’s explore how signals can be used in both simple and complex form scenarios.</p>
    
    <h3>
      
      
      Example 1: A Simple Template-Driven Form with Signals
    </h3>
    
    <p>Consider a basic login form. Typically, this would be implemented using template-driven forms like this:<br>
    </p>
    
    <pre class="brush:php;toolbar:false"><!-- login.component.html -->
    <form name="form" (ngSubmit)="onSubmit()">
      <label for="email">E-mail</label>
      <input type="email">
    
    
    
    
    
    <pre class="brush:php;toolbar:false">// login.component.ts
    import { Component } from "@angular/core";
    
    @Component({
      selector: "app-login",
      templateUrl: "./login.component.html",
    })
    export class LoginComponent {
      public email: string = "";
      public password: string = "";
    
      onSubmit() {
        console.log("Form submitted", { email: this.email, password: this.password });
      }
    }
    

    這種方法適用於簡單的表單,但是透過引入訊號,我們可以在添加反應(yīng)功能的同時保持簡單性:

    // login.component.ts
    import { Component, computed, signal } from "@angular/core";
    import { FormsModule } from "@angular/forms";
    
    @Component({
      selector: "app-login",
      standalone: true,
      templateUrl: "./login.component.html",
      imports: [FormsModule],
    })
    export class LoginComponent {
      // Define signals for form fields
      public email = signal("");
      public password = signal(""); // Define a computed signal for the form value
    
      public formValue = computed(() => {
        return {
          email: this.email(),
          password: this.password(),
        };
      });
    
      public isFormValid = computed(() => {
        return this.email().length > 0 && this.password().length > 0;
      });
    
      onSubmit() {
        console.log("Form submitted", this.formValue());
      }
    }
    
    <!-- login.component.html -->
    <form name="form" (ngSubmit)="onSubmit()">
      <label for="email">E-mail</label>
      <input type="email">
    
    
    
    <p>In this example, the form fields are defined as signals, allowing for reactive updates whenever the form state changes. The formValue signal provides a computed value that reflects the current state of the form. This approach offers a more declarative way to manage form state and reactivity, combining the simplicity of template-driven forms with the power of signals.</p>
    
    <p>You may be tempted to define the form directly as an object inside a signal. While such an approach may seem more concise, typing into the individual fields does not dispatch reactivity updates, which is usually a deal breaker. Here’s an example StackBlitz with a component suffering from such an issue:</p>
    
    <p>Therefore, if you'd like to react to changes in the form fields, it's better to define each field as a separate signal. By defining each form field as a separate signal, you ensure that changes to individual fields trigger reactivity updates correctly. </p>
    
    <h3>
      
      
      Example 2: A Complex Form with Signals
    </h3>
    
    <p>You may see little benefit in using signals for simple forms like the login form above, but they truly shine when handling more complex forms. Let's explore a more intricate scenario - a user profile form that includes fields like firstName, lastName, email, phoneNumbers, and address. The phoneNumbers field is dynamic, allowing users to add or remove phone numbers as needed.</p>
    
    <p>Here's how this form might be defined using signals:<br>
    </p>
    
    <pre class="brush:php;toolbar:false">// user-profile.component.ts
    import { JsonPipe } from "@angular/common";
    import { Component, computed, signal } from "@angular/core";
    import { FormsModule, Validators } from "@angular/forms";
    
    @Component({
      standalone: true,
      selector: "app-user-profile",
      templateUrl: "./user-profile.component.html",
      styleUrls: ["./user-profile.component.scss"],
      imports: [FormsModule, JsonPipe],
    })
    export class UserProfileComponent {
      public firstName = signal("");
      public lastName = signal("");
      public email = signal(""); 
      // We need to use a signal for the phone numbers, so we get reactivity when typing in the input fields
      public phoneNumbers = signal([signal("")]);
      public street = signal("");
      public city = signal("");
      public state = signal("");
      public zip = signal("");
    
      public formValue = computed(() => {
        return {
          firstName: this.firstName(),
          lastName: this.lastName(),
          email: this.email(), // We need to do a little mapping here, so we get the actual value for the phone numbers
          phoneNumbers: this.phoneNumbers().map((phoneNumber) => phoneNumber()),
          address: {
            street: this.street(),
            city: this.city(),
            state: this.state(),
            zip: this.zip(),
          },
        };
      });
    
      public formValid = computed(() => {
        const { firstName, lastName, email, phoneNumbers, address } = this.formValue(); // Regex taken from the Angular email validator
    
        const EMAIL_REGEXP = /^(?=.{1,254}$)(?=.{1,64}@)[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
        const isEmailFormatValid = EMAIL_REGEXP.test(email);
    
        return (
          firstName.length > 0 &&
          lastName.length > 0 &&
          email.length > 0 &&
          isEmailFormatValid &&
          phoneNumbers.length > 0 && // Check if all phone numbers are valid
          phoneNumbers.every((phoneNumber) => phoneNumber.length > 0) &&
          address.street.length > 0 &&
          address.city.length > 0 &&
          address.state.length > 0 &&
          address.zip.length > 0
        );
      });
    
      addPhoneNumber() {
        this.phoneNumbers.update((phoneNumbers) => {
          phoneNumbers.push(signal(""));
          return [...phoneNumbers];
        });
      }
    
      removePhoneNumber(index: number) {
        this.phoneNumbers.update((phoneNumbers) => {
          phoneNumbers.splice(index, 1);
          return [...phoneNumbers];
        });
      }
    }
    

    請注意,phoneNumbers 欄位被定義為訊號數(shù)組中的一個訊號。這種結(jié)構(gòu)使我們能夠追蹤各個電話號碼的變更並反應(yīng)性地更新表單狀態(tài)。 addPhoneNumber 和removePhoneNumber 方法更新phoneNumbers 訊號數(shù)組,觸發(fā)表單中的反應(yīng)性更新。

    <!-- user-profile.component.html -->
    
    
    
    
    <blockquote>
    <p>在範(fàn)本中,我們使用phoneNumbers訊號陣列來動態(tài)渲染電話號碼輸入欄位。 addPhoneNumber 和removePhoneNumber 方法允許使用者反應(yīng)性地新增或刪除電話號碼,從而更新表單狀態(tài)。請注意 track 函數(shù)的用法,這是確保 ngFor 指令正確追蹤phoneNumbers 陣列變更所必需的。 </p>
    </blockquote>
    
    <p>這是複雜表單範(fàn)例的 StackBlitz 演示,供您試用:</p>
    
    <h3>
      
      
      使用訊號驗證表單
    </h3>
    
    <p>驗證對於任何表單都至關(guān)重要,確保使用者輸入在提交之前符合所需的標(biāo)準。使用訊號,可以以反應(yīng)性和聲明性的方式處理驗證。在上面的複雜表單範(fàn)例中,我們實作了一個名為 formValid 的計算訊號,它檢查所有欄位是否符合特定的驗證標(biāo)準。 </p>
    
    <p>可以輕鬆自訂驗證邏輯以適應(yīng)不同的規(guī)則,例如檢查有效的電子郵件格式或確保填寫所有必填欄位。使用訊號進行驗證可以讓您建立更多可維護和可測試的程式碼,因為驗證規(guī)則被明確定義並自動對表單欄位中的變更做出反應(yīng)。它甚至可以被抽象化為單獨的實用程序,以使其可以在不同形式中重複使用。 </p>
    
    <p>在複雜表單範(fàn)例中,formValid 訊號可確保填寫所有必填欄位並驗證電子郵件和電話號碼格式。 </p>
    
    <p>這種驗證方法有點簡單,需要更好地連接到實際的表單欄位。雖然它適用於許多用例,但在某些情況下,您可能需要等到 Angular 中添加明確「訊號形式」支援。 Tim Deschryver 開始實現(xiàn)一些圍繞著訊號形式的抽象,包括驗證,並寫了一篇關(guān)於它的文章。讓我們看看將來 Angular 中是否會添加這樣的東西。 </p>
    
    <h3>
      
      
      為什麼要使用角度形式的訊號?
    </h3>
    
    <p>Angular 中訊號的採用提供了一種強大的新方法來管理表單狀態(tài)和反應(yīng)性。訊號提供了一種靈活的聲明性方法,可以透過結(jié)合模板驅(qū)動表單和反應(yīng)式表單的優(yōu)勢來簡化複雜的表單處理。以下是使用 Angular 形式的訊號的一些主要好處:</p>
    
    <ol>
    <li><p><strong>聲明式狀態(tài)管理</strong>:訊號可讓您以聲明方式定義表單欄位和計算值,讓您的程式碼更可預(yù)測且更易於理解。 </p></li>
    <li><p><strong>反應(yīng)性</strong>:訊號為表單欄位提供反應(yīng)性更新,確保表單狀態(tài)的變更自動觸發(fā)反應(yīng)性更新。 </p></li>
    <li><p><strong>粒度控制</strong>:訊號可讓您在粒度層級定義表單字段,從而實現(xiàn)對表單狀態(tài)和驗證的細粒度控制。 </p></li>
    <li><p><strong>動態(tài)表單</strong>:訊號可用於建立具有可動態(tài)新增或刪除欄位的動態(tài)表單,提供靈活的方式來處理複雜的表單場景。 </p></li>
    <li><p><strong>簡單性</strong>:與傳統(tǒng)的反應(yīng)式表單相比,訊號可以提供更簡單、更簡潔的方式來管理表單狀態(tài),使建置和維護複雜表單變得更加容易。 </p></li>
    </ol>
    
    <h3>
      
      
      結(jié)論
    </h3>
    
    <p>在我之前的文章中,我們探索了 Angular 反應(yīng)式表單的強大功能,從動態(tài)表單建置到自訂表單控制項。隨著訊號的引入,Angular 開發(fā)人員擁有了一種新工具,它將模板驅(qū)動表單的簡單性與反應(yīng)式表單的反應(yīng)性融為一體。 </p>
    
    <p>雖然許多用例都需要反應(yīng)式表單,但訊號為需要更直接、聲明性方法的 Angular 應(yīng)用程式中的表單狀態(tài)管理提供了一種全新、強大的替代方案。隨著 Angular 的不斷發(fā)展,嘗試這些新功能將幫助您建立更易於維護、性能更高的應(yīng)用程式。 </p>
    
    <p>編碼愉快! </p>
    
    
              
    
                
            

以上是探索角度形式:訊號的新替代方案的詳細內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Java vs. JavaScript:清除混亂 Java vs. JavaScript:清除混亂 Jun 20, 2025 am 12:27 AM

Java和JavaScript是不同的編程語言,各自適用於不同的應(yīng)用場景。 Java用於大型企業(yè)和移動應(yīng)用開發(fā),而JavaScript主要用於網(wǎng)頁開發(fā)。

JavaScript評論:簡短說明 JavaScript評論:簡短說明 Jun 19, 2025 am 12:40 AM

JavascriptconcommentsenceenceEncorenceEnterential gransimenting,reading and guidingCodeeXecution.1)單inecommentsareusedforquickexplanations.2)多l(xiāng)inecommentsexplaincomplexlogicorprovideDocumentation.3)

如何在JS中與日期和時間合作? 如何在JS中與日期和時間合作? Jul 01, 2025 am 01:27 AM

JavaScript中的日期和時間處理需注意以下幾點:1.創(chuàng)建Date對像有多種方式,推薦使用ISO格式字符串以保證兼容性;2.獲取和設(shè)置時間信息可用get和set方法,注意月份從0開始;3.手動格式化日期需拼接字符串,也可使用第三方庫;4.處理時區(qū)問題建議使用支持時區(qū)的庫,如Luxon。掌握這些要點能有效避免常見錯誤。

為什麼要將標(biāo)籤放在的底部? 為什麼要將標(biāo)籤放在的底部? Jul 02, 2025 am 01:22 AM

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

JavaScript與Java:開發(fā)人員的全面比較 JavaScript與Java:開發(fā)人員的全面比較 Jun 20, 2025 am 12:21 AM

JavaScriptIspreferredforredforwebdevelverment,而Javaisbetterforlarge-ScalebackendsystystemsandSandAndRoidApps.1)JavascriptexcelcelsincreatingInteractiveWebexperienceswebexperienceswithitswithitsdynamicnnamicnnamicnnamicnnamicnemicnemicnemicnemicnemicnemicnemicnemicnddommanipulation.2)

JavaScript:探索用於高效編碼的數(shù)據(jù)類型 JavaScript:探索用於高效編碼的數(shù)據(jù)類型 Jun 20, 2025 am 12:46 AM

javascripthassevenfundaMentalDatatypes:數(shù)字,弦,布爾值,未定義,null,object和symbol.1)numberSeadUble-eaduble-ecisionFormat,forwidevaluerangesbutbecautious.2)

什麼是在DOM中冒泡和捕獲的事件? 什麼是在DOM中冒泡和捕獲的事件? Jul 02, 2025 am 01:19 AM

事件捕獲和冒泡是DOM中事件傳播的兩個階段,捕獲是從頂層向下到目標(biāo)元素,冒泡是從目標(biāo)元素向上傳播到頂層。 1.事件捕獲通過addEventListener的useCapture參數(shù)設(shè)為true實現(xiàn);2.事件冒泡是默認行為,useCapture設(shè)為false或省略;3.可使用event.stopPropagation()阻止事件傳播;4.冒泡支持事件委託,提高動態(tài)內(nèi)容處理效率;5.捕獲可用於提前攔截事件,如日誌記錄或錯誤處理。了解這兩個階段有助於精確控制JavaScript響應(yīng)用戶操作的時機和方式。

Java和JavaScript有什麼區(qū)別? Java和JavaScript有什麼區(qū)別? Jun 17, 2025 am 09:17 AM

Java和JavaScript是不同的編程語言。 1.Java是靜態(tài)類型、編譯型語言,適用於企業(yè)應(yīng)用和大型系統(tǒng)。 2.JavaScript是動態(tài)類型、解釋型語言,主要用於網(wǎng)頁交互和前端開發(fā)。

See all articles