检测子组件中 ng-model 的变化并在 AngularJS 中传递数据

Detect changes to ng-model in child component and pass the data in AngularJS

我正在创建一个基于 angular 1.5.8 应用程序的大型组件。父组件中大约有 18 个不同的组件。为此,每个组件模板都有作为父组件表单一部分的输入。到目前为止一切正常。我坚持并且真正需要逻辑的是如何检测对每个组件中的输入所做的更改,以便可以将数据保存在共享服务中,供父组件在将表单数据发送到服务器之前获取.

来自父组件

<form name="claimForm" novalidate>
    <!-- Section Title  -->
    <section name="Add new claim" class="section-background section animated fadeIn" ng-cloak>

        <!-- Pharmacy Info -->
        <pharmacy-info claim-form="claimForm"></pharmacy-info>

    </section>
</form>

PharmacyInfo 只有一个简单的输入

<md-input-container flex-gt-sm="70">
    <label>Pharmacy Name</label>
    <input type="text"
            flex
            tabindex="4"
            id="pharmacyName"
            name="pharmacyName"
            md-maxlength="80"
            aria-label="Pharmacy Name"
            ng-model="$ctrl.pharmacy.name" />
    <div ng-messages="$ctrl.claimForm.pharmacyName.$error">
        <div ng-message="md-maxlength">
            Pharmacy name is too long!
        </div>
    </div>
</md-input-container>

药剂部分

(function () {
    'use strict';

    angular.module('sempp')
        .component('pharmacyInfo', {
            templateUrl: 'Scripts/src/views/pharmacy/pharmacy.info.template.html',
            controller: PharmacyInfoComponentController,
            bindings: {
                claimForm: '<'
            }
        });

    PharmacyInfoComponentController.$inject = ['PharmacyService']

    function PharmacyInfoComponentController(PharmacyService) {
        var $ctrl = this;


        $ctrl.$doCheck = function () {

            //console.log($ctrl.pharmacy);
            PharmacyService.setPharmacy($ctrl.pharmacy);
        }


    }// end controller function

})();

我遇到的问题是,我不能在每个组件上都有一个 "update" 按钮,供用户在每次在表单中输入值时单击。它不会太用户友好。

我 运行 关注的另一个问题是使用 $onChanges。它没有检测到对子组件中的表单所做的任何更改。不知道如何做到这一点。不过,我仍在阅读文档。

但是,如果我使用 $doCheck,它会检测到更改,但每次我对表单进行任何更改时它都是 运行。现在,大约有 18 个组件和每个组件中的许多输入表单,我认为这只会减慢应用程序的速度。

我有什么选择?我怎样才能做到无缝,以便当用户输入值时,该值要么保存在共享服务中,要么保存在父组件对象中(以更好的为准)。然后我需要将数据发送到要插入的数据库。

确保您的父组件可以查看子组件中所做的更改,并且您可以在父组件中执行类似的操作:

$scope.$watch(function() {
   return ctrl.pharmacy
}, function(){
    // do your updates here within the parent function
});

当然,这意味着您必须将 $scope 注入到您的父控制器中,但我通常发现这是处理此问题的最简单方法。

对输入使用 ng-change 指令:

<md-input-container flex-gt-sm="70">
    <label>Pharmacy Name</label>
    <!-- USE ng-change directive -->
    <input type="text"
            ng-change="$ctrl.updatePharmacyService()"               
            flex
            tabindex="4"
            id="pharmacyName"
            name="pharmacyName"
            md-maxlength="80"
            aria-label="Pharmacy Name"
            ng-model="$ctrl.pharmacy.name" />
    <div ng-messages="$ctrl.claimForm.pharmacyName.$error">
        <div ng-message="md-maxlength">
            Pharmacy name is too long!
        </div>
    </div>
</md-input-container>

ng-change 指令仅在用户输入时评估其 AngularJS 表达式。与使用评估每个摘要周期的 $doCheck 函数相比,这将有更少的开销。

有关详细信息,请参阅