在组件控制器中获取绑定对象

Get binded object inside component controller

Angular1.6

我不明白为什么我无法访问组件控制器中绑定的 self.widget 对象。 console.log(self.widget); 输出 undefined。但是我通过 $ctrl.widget 访问了模板中的 widget 对象,小部件有效。

当我这样做时,我在浏览器控制台中看到了对象 angular.element([=18=]).scope().$ctrl

组件:

import template from './templates/clock-widget.template.html';
import controller from './clock-widget.controller';

const clockWidget = {
    bindings: {
        widget: '<'
    },
    controller,
    template
};

export default clockWidget;

组件的控制器:

import controller from './clock-widget.settings.controller.js';
import template from './templates/clock-widget.settings.template.html';

import 'angular-clock/dist/angular-clock.css';
import './style.css';

import timezones from './timezones';

const injectParams = ['$scope', '$timeout', '$uibModal'];
const ClockWidgetCtrl = function($scope, $timeout, $uibModal) {
    const self = this;

    self.gmtOffset = 2;
    console.log(self.widget);

    self.openSettings = function() {
        $uibModal.open({
            scope: $scope,
            controllerAs: '$ctrl',
            controller,
            template,
            resolve: {
                widget: function() {
                    return self.widget;
                }
            }
        });
    };
};

ClockWidgetCtrl.$inject = injectParams;
export default ClockWidgetCtrl;

组件模板:

<div class="box clock-widget">
    <div class="box-header">
        <h3>{{ $ctrl.widget.title }}</h3>
        <div class="box-header-btns pull-right">
            <a title="settings" ng-click="$ctrl.openSettings(widget)"><i class="glyphicon glyphicon-cog"></i></a>
            <a title="Remove widget" ng-click="$ctrl.remove(widget)"><i class="glyphicon glyphicon-trash"></i></a>
        </div>
    </div> <!-- END box-header -->

    <div class="box-content">
        <b>{{$ctrl.widget.config.location.split('/')[1]}}</b>
        <ds-widget-clock gmt-offset="$ctrl.gmtOffset" show-analog show-gmt-info></ds-widget-clock>
    </div> <!-- END box-content -->
</div> <!-- END box -->

Directive/component构造控制器时模板尚未编译,绑定也未分配给控制器实例。

根据the reference,

After the controller is instantiated, the initial values of the isolate scope bindings will be bound to the controller properties. You can access these bindings once they have been initialized by providing a controller method called $onInit, which is called after all the controllers on an element have been constructed and had their bindings initialized.

此行为由 $compileProvider.preAssignBindingsEnabled 控制:

Call this method to enable/disable whether directive controllers are assigned bindings before calling the controller's constructor. If enabled (true), the compiler assigns the value of each of the bindings to the properties of the controller object before the constructor of this object is called.

If disabled (false), the compiler calls the constructor first before assigning bindings.

The default value is true in Angular 1.5.x but will switch to false in Angular 1.6.x.

所有与绑定和 DOM 相关的逻辑都应放在 $onInit$postLink 钩子中(指令 pre/post-link 函数的较新替代方案):

self.$onInit = function () {
    console.log(self.widget);
}