anchor.diff:    It presents a list of questions, each question bound to a `<df-question>` component element.
     The `<df-question>` tag matches the `DynamicFormQuestionComponent`,
     the component responsible for rendering the details of each _individual_ question based on values in the data-bound question object.  
  -
  +  
  +  它显示一个问卷问题的列表，每个问题都在`<df-question>`组件元素之内。`<df-question>`对应于`DynamicFormQuestionComponent`，该组件的作用是根据问卷问题对象的值来渲染每个问卷问题的细节。
  +  
   +makeTabs(
     `cb-dynamic-form/ts/app/dynamic-form-question.component.html,
      cb-dynamic-form/ts/app/dynamic-form-question.component.ts`,
  
positive.code:   We only have two types of questions at this point but we can imagine many more.
    The `ngSwitch` determines which type of question to display.
    
    In both components  we're relying on Angular's **ngFormModel** to connect the template HTML to the
    underlying control objects, populated from the question model with display and validation rules.
  
  <a id="questionnaire-metadata"></a>
  :marked
     ## Questionnaire data
  :marked
    `DynamicForm` expects the list of questions in the form of an array bound to  `@Input() questions`.
  
     The set of questions we have defined for the job application is returned from the `QuestionService`. 
     In a real app we'd retrieve these questions from storage.
     
     The key point is that we control the hero job application questions entirely through the objects returned from `QuestionService`. 
     Questionnaire maintenance is a simple matter of adding, updating, and removing objects from the `questions` array.
     
  +makeExample('cb-dynamic-form/ts/app/question.service.ts','','app/question.service.ts')  
  
  :marked
    Finally, we display an instance of the form in the `AppComponent` shell.
  
  +makeExample('cb-dynamic-form/ts/app/app.component.ts','','app.component.ts')
  
  <a id="dynamic-template"></a>
  :marked
     ## Dynamic Template
     Although in this example we're modelling a job application for heroes, there are no references to any specific hero question 
     outside the objects returned by `QuestionService`. 
     
     This is very important since it allows us to repurpose the components for any type of survey
     as long as it's compatible with our *question* object model. 
     The key is the dynamic data binding of metadata used to render the form 
     without making any hardcoded assumptions about specific questions. 
     In addition to control metadata, we are also adding validation dynamically.
  
     The *Save* button is disabled until the form is in a valid state. 
     When the form is valid, we can click *Save* and the app renders the current form values as JSON. 
     This proves that any user input is bound back to the data model.
     Saving and retrieving the data is an exercise for another time.
  
  :marked
     The final form looks like this:
  figure.image-display
     img(src="/resources/images/cookbooks/dynamic-form/dynamic-form.png" alt="Dynamic-Form")
  
  
  :marked
     [Back to top](#top)
negative.code:    From this base we derived two new classes in `TextboxQuestion` and `DropdownQuestion` that represent Textbox and Dropdown questions. 
     The idea is that the form will be bound to specific question types and render the appropriate controls dynamically. 
     
     在这个基础上，我们衍生了两个新类`TextboxQuestion` 和 `DropdownQuestion`，分别代表文本框和下拉框。这么做的初衷是，表单能动态的绑定特定的问卷问题类型，并动态渲染合适的控制器。
     
     `TextboxQuestion` supports multiple html5 types like text, email, url etc via the `type` property.
     
     `TextboxQuestion`通过`type`属性，支持多种HTML5元素类型，比如文本、邮件、网址等。
  
  +makeExample('cb-dynamic-form/ts/app/question-textbox.ts',null,'app/question-textbox.ts')(format='.')
  
  :marked
     `DropdownQuestion` presents a list of choices in a select box.
     
     `DropdownQuestion`代表一个拥有一个列表可选项目的选择框。
     
  +makeExample('cb-dynamic-form/ts/app/question-dropdown.ts',null,'app/question-dropdown.ts')(format='.')
  
  :marked
     Next we have defined `QuestionControlService`, a simple service for transforming our questions to an ngForm control group. 
     In a nutshell, the control group consumes the metadata from the question model and allows us to specify default values and validation rules.
     
     下一步，我们定义了`QuestionControlService`，一个可以把我们的问卷问题转换为ngForm控制组的服务。简而言之，这个ngForm控制组使用问卷模型的元数据，允许我们制定默认值和验证规则。
  +makeExample('cb-dynamic-form/ts/app/question-control.service.ts',null,'app/question-control.service.ts')(format='.')
  
  <a id="form-component"></a>
  :marked
     ## Question form components
     ## 问卷表单组件
     
     Now that we have defined the complete model we are ready to create components to represent the dynamic form.
     现在我们已经有一个已定义的完整模型，我们可以创建一个动态表单的组件。
  
  :marked
    `DynamicForm` is the entry point and the main container for the form.
    
    `DynamicForm`是我们表单的主要载体和切入口。 
  +makeTabs(
    `cb-dynamic-form/ts/app/dynamic-form.component.html,
     cb-dynamic-form/ts/app/dynamic-form.component.ts`,
  