angular 组件 one-time 来自 $http 的绑定显示未定义

angular component one-time binding from $http shows undefined

我是 Angular 的新手。我正在尝试使用组件 (1.6)。在 parent 中,我有一个 $http.get 从服务获取数据,然后将响应分配给 $scope 变量。该范围变量使用 one-way 绑定 < 传递给 child 组件。在 JavaScript 中,如果我提醒传入的变量,我会得到 "undefined",但是,child 中的 html 模板确实显示了该变量。就像发生了竞争条件,我不知道如何告诉它等待服务数据加载完毕。

在我的 parent.js:

(function (angular) {
    'use strict';
    $http.get("http://localhost:52422/api/PayOffYourCc")
    .then(function mySucces(response) {
        $scope.baseline = response.data;

    }
    ,
    function myError(respone) {
        $scope.baseline = response.statusText;

    }
    );
})(window.angular);

在我的 parent HTML 模板中:

<thermometer baseline="baseline"></thermometer>

在我的 child 组件中:

(function (angular) {
    'use strict';

    function drawChart(baselineVal) {
        alert(baselineVal);
    }

    function ThermometerController($scope) {
        var ctrl = this;
        ctrl.$onInit = function () {
            drawChart(ctrl.baseline);
        };


    }

    angular.module('payOffYourCcApp').component('thermometer', {
        templateUrl: '../PayOffYourCC/partials/thermometer.html',
        transclude: true,
        controller: ThermometerController,
        bindings: {
            baseline: '<'
        }
    });
})(window.angular);

在我的 child html 模板中:

<div>
    baseline:{{$ctrl.baseline}}
</div>

在 html 中,{{$ctrl.baseline}} 显示正常,但是当我在 .js 中提醒它时,它是 undefined。这是为什么?如何确保 {{$ctrl.baseline}} 在 javascript 加载之前在范围内?

使用 Angular 组件,您应该将通信特权从 child 返回到 parent,因为它允许非常便宜的绑定 (&)

您可以从 parent 通信到 child,但它更昂贵 (=)。
我将举例说明如何操作。
这是一个未经测试的解决方案,但您应该知道。

您应该将 parent 更改为 child api 来传输数据:

JS Parent :

(function (angular) {
    'use strict';
    $http.get("http://localhost:52422/api/PayOffYourCc")
    .then(function mySucces(response) {
        $scope.baseline = response.data;
        $ctrl.apiChild.transmit(response.data);
    }
    ,
    function myError(respone) {
        $scope.baseline = response.statusText;
    }
    );
})(window.angular);

HTML Parent :

<thermometer api="$ctrl.apiChild"></thermometer>

将您的 child 更改为具有从 parent 接收数据的功能,并将绑定更改为 "=" :

JS Child :

(function (angular) {

'use strict';

function drawChart(baselineVal) {
    alert(baselineVal);
}

function ThermometerController($scope) {
    var ctrl = this;
    ctrl.$onInit = function () {
        drawChart(ctrl.baseline);
        ctrl.api = {};
        ctrl.api.transmit = ctrl.transmitData;
    };

   this.transmitData = function transmitData(data){
        // here you get the data from the parent to the child
   }

}

angular.module('payOffYourCcApp').component('thermometer', {
    templateUrl: '../PayOffYourCC/partials/thermometer.html',
    transclude: true,
    controller: ThermometerController,
    bindings: {
        api : '='
    }
});
})(window.angular);

这是 $http 请求异步的结果。子组件初始化时发生的警报打印 undefined,因为此时正在检索数据的 $http 请求尚未返回。但是,由于您使用的是 > 绑定,因此您的子组件中的模板将在请求解析后立即更新为正确的值(这非常快),因此您永远不会看到 undefined 实际上打印在模板中。事实上,我不认为 angular 会打印出 undefined,我认为它只是一个空白。因此,在您看来,它似乎立即具有正确的值,而实际上,它在 $http 请求解析时暂时未定义。

使用 $onChanges 生命周期挂钩:

function ThermometerController($scope) {
    var ctrl = this;
    /* REPLACE THIS
    ctrl.$onInit = function () {
        drawChart(ctrl.baseline);
    }; */
    // WITH THIS
    ctrl.$onChanges = function (changesObj) {
        if (changesObj.baseline && changesObj.baseline.currentValue) {
            drawChart(changesObj.baseline.currentValue);
        };
    };
}

控制器需要等待服务器传来数据。通过使用 $onChanges 生命周期挂钩,drawChart 函数将在数据可用时调用,并将在后续更新时调用。

有关详细信息,请参阅 AngularJS Comprehensive Directive API Reference - Life-Cycle Hooks