Angular中的动态表单控件

时间:2017-04-24 15:41:36

标签: angular

我有一个首选屏幕,用户注册各种服务,这些服务是从服务中接收的。

我的Json就是这种东西

[   {
      category : 'General',
      source :    [   { name: 'ABC News', url: 'abc-news-au', subscribed: false},
                      { name: 'Associated Press', url: 'associated-press', subscribed: false}],
      numberofarticles: 4
   },
 repeat above node multiple times 
]

因此,该服务可以发送X用户可以订阅的不同类别。然后在每个类别中,他都可以选择他想要订阅的新闻频道。

我正在构建首选项屏幕,并且我对如何创建动态UI有点困惑,其中所有这些都列出了&用户选择传输到服务器进行更新/保存。

使用模板驱动的方法很容易创建表单,但发送值不起作用。

很高兴 - 此外,我正在尝试找到一种方法,用户所做的任何更新都会直接保存到json,这样我就不会手动检查用户所做的每次点击并更新json 。对于例如如果用户选中了ABC新闻'渠道订阅的选项变为True。

模板表单

form (ngSubmit)="onSubmit(f)" #f="ngForm">
  <md-tab-group>
     <md-tab *ngFor="let news of newsList" label={‌{news.category}}>

       <h3 color="accent">Select news sources</h3>
       <md-select multiple placeholder="" ngModel name="{‌{news.source}}">
          <md-option *ngFor="let source of news.source" [value]="source.name">
             {‌{source.name}}
         </md-option>
       </md-select>
      <br>

      <h3>Number of new articles of each topic</h3>
      <md-slider ngModel #numberofArticles name="numberofArticles" min="1" max="5" step="1"
         value={‌{news.NoOfArticles}} tickInterval="auto" thumbLabel></md-slider>
      <br>

     </md-tab>
   </md-tab-group>
 <br>
 <button md-raised-button color="primary" type="submit" >Save</button>
</form>

由于

2 个答案:

答案 0 :(得分:0)

您可能需要使用ReactiveFormsModule而不是FormsModule,您可以在TS中动态构建from。您可以阅读REACTIVE FORMS

答案 1 :(得分:0)

我设法用模板驱动的表单来做,反应式表单不适合我的场景。 {如果有人找到反应形式的方法,请告诉我}

除了我添加索引以具有唯一名称

之外,html或多或少相同

模板表单

 <form (ngSubmit)="onSubmit(f)" #f="ngForm">

<md-tab-group>
  <md-tab *ngFor="let news of newsList; let i=index"
            label={{news.category}}
            ngModelGroup={{news.category}}
            #{{news.category}}="ngModelGroup"
            >
      <h3 color="accent">Select news sources</h3>
        <br>
         <section class="example-section" ngModelGroup="news">
              <md-checkbox ngModel class="example-margin"
                           name={{news.category}}_{{x}}
                          *ngFor="let source of news.source; let x=index"
                           [(ngModel)]="source.subscribed">
                  {{source.name}}
              </md-checkbox>
          </section>

        <h3>Number of new articles of each topic</h3>
        <md-slider ngModel name="numberofArticles_{{i}}"
                  min="1" max="5" step="1"
                  value={{news.NoOfArticles}} tickInterval="auto"
                  thumbLabel>
        </md-slider>
        <br>
    </md-tab>
  </md-tab-group>
  <br>
  <button md-raised-button color="primary" type="submit" >Save</button>
 </form>

通过这个我循环的每个类别都有一个唯一的节点名称。此外,我使用ngModelGroup对元素进行了分组,这在以后帮助了很多。

组件代码

 onSubmit(f: NgForm) {
     // Check if form is dirty
      if (f.dirty) {
            const myControls = f.controls;
            let i = 0;
            // Update the user preferences based on what he selected on the ui. DefaultNews is my model data which is needs to be updated
            const defaultCategories = DefaultNews.defaultNews;

            defaultCategories.forEach(element => {
               // Check if the news category is dirty - i.e. each Tab on the UI
                if ((myControls[element.category]).dirty) {
                   // check if news websites were touched i.e. if any checkbox from the group is updated
                   if ((myControls[element.category].get('news')).dirty) {
                      let newsSubscription;
                      let index = 0;
                      // Read thru each news source and set it from the ui
                      element.source.forEach(newsSource => {
                             newsSubscription = (myControls[element.category].get('news')).get(element.category + '_' + index);
                             newsSource.subscribed = newsSubscription.value;
                             index = index + 1;
                      });
                   }
                   // check if the number of articles was touched - i.e. if slider was moved
                   if ((myControls[element.category].get('numberofArticles_' + i)).dirty) {
                     element.NoOfArticles = (myControls[element.category].get('numberofArticles_' + i)).value;
                   }

                   i = i + 1;
                }
            });
      }
  }

如果是,则检查表单是否为脏,然后检查特定节点是否为脏,如果是,则再次更新用户首选项。

我附上了屏幕截图,以了解偏好设置屏幕是什么。我在元素和零样式方面保持简单,以便更容易看到实际的代码。

First Tab of Preferences screen

Second Tab of Preferences screen