来自$ http的角度组件一次性绑定显示未定义

时间:2016-12-19 17:19:38

标签: angularjs angularjs-http angularjs-components

我是Angular的新手。我正在尝试使用组件(1.6)。在父级中,我有$http.get从服务获取数据,然后将响应分配给$scope变量。该范围变量使用单向绑定<传递给子组件。在JavaScript中,如果我警告传入的变量,我会得到“未定义”,但是,子项中的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);

在我的父HTML模板中:

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

在我的孩子组件中:

(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);

在我的孩子html模板中:

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

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

3 个答案:

答案 0 :(得分:1)

使用$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

答案 1 :(得分:0)

使用Angular组件,您应该将来自子项的通信权限转回给父项,因为它允许非常便宜的绑定(&

您可以从父母与孩子沟通,但费用更高(=) 我将举例说明如何做到这一点 这是一个未经过测试的解决方案,但你应该有这个想法。

您应该更改您的父级以使子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>

将您的孩子更改为具有从父母接收数据的功能,并将绑定更改为"="

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);

答案 2 :(得分:0)

这是$ http请求异步的结果。子组件初始化时发生的警报打印undefined,因为在该实例中,尚未返回检索数据的$ http请求。但是,由于您正在使用>绑定,因此只要请求结算,您子组件中的模板就会使用正确的值进行更新(这非常快),所以您再也看不到了undefined实际打印在模板中。事实上,我并不认为棱镜会打印出未定义的,我认为它只是空白。所以对你来说,它看起来就像它具有正确的价值,实际上,当$ http请求解析时它暂时未定义。