Reputation: 5634
Angular 1.6
I can't understand why I don't have access to the binded self.widget
object in my component controller. The console.log(self.widget);
prints undefined
. But I get access to the widget
object in template via $ctrl.widget
, the widget works.
And I see the object in browser console when I do angular.element($0).scope().$ctrl
Component:
import template from './templates/clock-widget.template.html';
import controller from './clock-widget.controller';
const clockWidget = {
bindings: {
widget: '<'
},
controller,
template
};
export default clockWidget;
Controller of the component:
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;
Component template:
<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 -->
Upvotes: 1
Views: 502
Reputation: 222750
Directive/component template hasn't been compiled yet at the moment when a controller is constructed, and bindings aren't assigned to controller instance as well.
According to 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.
This behaviour is controlled by $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.
All logic that is related to bindings and DOM should be placed inside $onInit
or $postLink
hook (newer alternatives to directive pre/post-link functions):
self.$onInit = function () {
console.log(self.widget);
}
Upvotes: 1