如何在AngularJS中实现带有输入字段的模板组件

Posted

技术标签:

【中文标题】如何在AngularJS中实现带有输入字段的模板组件【英文标题】:How to realize template component with input field in AngularJS 【发布时间】:2020-01-29 20:28:14 【问题描述】:

我们在项目中使用 AngularJS 1.6 和 bootstrap 4.3.1 来构建 UI。现在我想构建一个简单的组件,它基本上可以更轻松地使用引导程序的表单组元素。

我尝试这样编写组件:

模板:

<div class="form-group">
<label
    for="input-::$ctrl.name"
    class="input-label mb-1"
    ng-class="'disabled': $ctrl.isDisabled, 'required': $ctrl.isRequired"
    ng-bind="::$ctrl.label">
</label>
<input
    tabindex="$ctrl.tabindex"
    ng-readonly="$ctrl.isReadonly"
    ng-model="$ctrl.model"
    type="::$ctrl.type"
    id="input-::$ctrl.name"
    class="form-control"
    ng-class="'negative': $ctrl.hasNegativeStyle"
    ng-required="$ctrl.isRequired">

javascript

(function () 
'use strict';

var component = 
    templateUrl: 'app/components/bootstrap/form-group-input/form-group-input.component.html',
    bindings: 
        name: '@',
        label: '@',
        model: '<',
        isReadonly: '<',
        isRequired: '<',
        isDisabled: '<',
        hasNegativeStyle: '<',
        type: '@',
        tabindex: '@'
    
;

angular
    .module('collphir.common')
    .component('cwpFormGroupInput', component);
)();

现在的问题是模型绑定。更改组件中的输入不会影响父模型,因为它是单向绑定的。但是,如果不回到旧的双向绑定(我们不想要,因为我们想很快迁移到 Angular),我怎么能实现呢?

【问题讨论】:

【参考方案1】:

我找到了实现我想要的方法:

JavaScript:

(function () 
'use strict';

var component = 
    templateUrl: 'app/components/bootstrap/form-group-input/form-group-input.component.html',
    bindings: 
        name: '@',
        label: '@',
        model: '<',
        isReadonly: '<',
        isRequired: '<',
        isDisabled: '<',
        hasNegativeStyle: '<',
        type: '@',
        tabindex: '@',
        modelChange: '&'
    
;

angular
    .module('collphir.common')
    .component('cwpFormGroupInput', component);
)();

HTML 模板:

<div class="form-group">
<label
    for="input-::$ctrl.name"
    class="input-label mb-1"
    ng-class="'disabled': $ctrl.isDisabled, 'required': $ctrl.isRequired"
    ng-bind="::$ctrl.label">
</label>
<input
    tabindex="$ctrl.tabindex"
    ng-readonly="$ctrl.isReadonly"
    ng-model="$ctrl.model"
    type="::$ctrl.type"
    id="input-::$ctrl.name"
    class="form-control"
    ng-class="'negative': $ctrl.hasNegativeStyle"
    ng-change="$ctrl.modelChange($event: $ctrl.model)"
    ng-required="$ctrl.isRequired">
</div>

该组件的使用示例:

<cwp-form-group-input
    class="mb-2"
    name="brutto"
    label="$ctrl.text.labelBrutto"
    model="$ctrl.sVEinkommen"
    is-readonly="$ctrl.isReadonly"
    type="number"
    model-change="$ctrl.sVEinkommen=$event"
    tabindex="1">
</cwp-form-group-input>

【讨论】:

【参考方案2】:

如果您希望子组件中的模型更改也反映在其父组件中,则必须使用双向绑定。所以在你的组件中,你可以像这样设置你的绑定:

bindings: 
    // ...
    model: '=',
    // ...

= 表示双向绑定,&lt; 表示单向绑定。直接看这个报价from the AngularJS documentation:

如果您将对象传递给像这样的组件 - bindings: item: '=',并修改其属性之一,则更改将反映在父组件中。

【讨论】:

是的,我知道,我正在使用组件一段时间。我的问题是如何通过单向绑定来实现这一点,但我想这是不可能的。通常我使用向下传递到组件中的回调函数,但因为它只是一个没有任何按钮的输入字段我不知道我的目标是否可能。 是的,我一定错过了您提到不想将其更改为双向绑定的部分。如果您无法更改绑定类型,那么您在答案中的做法是正确的。

以上是关于如何在AngularJS中实现带有输入字段的模板组件的主要内容,如果未能解决你的问题,请参考以下文章

如何在angularjs中实现导航栏

AngularJS中实现Model缓存

在AngularJS中实现一个延迟加载的Directive

如何在 AngularJS 中实现 websockets?

如何在 Web 表单中实现 AngularJS 控制器?

如何在 AngularJS 中实现组件组合(类似于 React 渲染道具模式)?