I'm trying to bind some values in an angular 1.6 component that should be available to the controller code.
I must be misunderstanding it, but the variables aren't available when the controller runs. The only way I've managed it is by putting a $timeout in to push the code into the next digest cycle.
What am I doing wrong here?
The relevant section is here:
var SelectorCtrl = ['$scope', '$http', '$timeout',
function ($scope, $http, $timeout) {
var self = this;
alert("1: " + self.hierarchyId);
// I'm not 100% sure why this has to be in the next digest cycle
$timeout(function(){
$scope.categories = self.categories;
alert("2: " + self.hierarchyId);
});
}
app.component('categorySelector', {
templateUrl: 'categorySelector.html',
controller: SelectorCtrl,
bindings: {
hierarchyId: "@",
disabled: "=",
categories: "=",
onSelectionChanged: "&"
}
});
See plunker: https://plnkr.co/edit/8rtDuCawdHaiXzQU5VBR
Angular's two-way binding syntax is a combination of square brackets and parentheses, [()] . The [()] syntax combines the brackets of property binding, [] , with the parentheses of event binding, () , as follows.
Data binding in AngularJS is the synchronization between the model and the view. When data in the model changes, the view reflects the change, and when data in the view changes, the model is updated as well.
The controller in AngularJS is a JavaScript function that maintains the application data and behavior using $scope object. You can attach properties and methods to the $scope object inside a controller function, which in turn will add/update the data and attach behaviours to HTML elements.
AngularJS creates a two way data-binding between the select element and the $ctrl.
This is because of $compileProvider.preAssignBindingsEnabled(flag)
introduced in Angular 1.6, you can configure it on config cycle on $compileProvider
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.
You will get all bindings inside $onInit
lifecycle event of Angular component, where all the bindings would be available(if binding passed synchronously).
self.$onInit = function() {
$scope.categories = self.categories;
alert("2: " + self.hierarchyId);
};
Note: It's bad practice to mix
$scope
withthis
. Rather avoid using$scope
to make your code Angular 2 migration proof.
If you want binding to be available when controller function instantiate then you could set $compileProvider.preAssignBindingsEnabled(true)
. Which will make self.categories
(bindings) value.
app.config(function($compileProvider){
$compileProvider.preAssignBindingsEnabled(true)
});
Similar answer
As of Angular 1.7.x, the $compileProvider.preAssignBindingsEnabled(flag)
is gone, and it is no longer possible to assign bindings before the constructor.
To work around this, you need to define a link
function in your directive definition. You can make this function call a method on your controller like this:
app.directive("directive", function() {
return {
controller: DirectiveController, // bind controller any way you want
controllerAs: "ctrl",
bindToController: true,
link: function(scope) {
scope.ctrl.init(); // this will call an init() function on your controller
}
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With