1

I'm trying to share some data from the controller in the current view to my navigation bar. but the data is shared wrong, or not synced correctly.

this is my factory:

myApp.factory('HeaderData', function () { var data = { Visible: true, PageTitle: '' }; return { getVisible: function () { return data.Visible; }, setVisible: function (visible) { data.Visible = visible; console.log("HeaderData: " +visible); }, getPageTitle: function () { return data.PageTitle; }, setPageTitle: function (title) { data.PageTitle = title; } }; }); 

then in my controllers I'm doing the following:

myApp.controller('homeCtrl',function ($scope, HeaderData) { HeaderData.setVisible(false); console.log("HomeCtrl: " + HeaderData.getVisible()); }); 

in the Nav controller I read the data in like following:

myApp.controller('navCtrl', function ($scope, HeaderData) { console.log("NavCtrl: " +HeaderData.getVisible()); $scope.showHeader = HeaderData.getVisible(); $scope.pageTitle = HeaderData.getPageTitle(); }); 

the following output is logged:

NavCtrl: true HeaderData: false HomeCtrl: false 

So my NavContrl is loaded before my Data is set, and this is logical because it's like this in the HTML:

<div ng-controller="navCtrl"> <ng-include ng-show="showHeader" src="'../partials/common/header.html'"></ng-include> </div> <div ng-view></div> 

So how can I make it work that my navCtrl updates the data correctly, and in this example hide the header when the $scope.showHeader is set to false?

1 Answer 1

2

Instead of assigning a primitive to $scope, assign an object to scope so that you can bind by reference. By binding by reference, you ensure that scope properties resolve to the same reference.

When you bind to a primitive (string, int, etc), it creates a copy of the original value on scope as soon as it is assigned. Now you have multiple copies of the variable on different scopes, and they all behave independently of each other.

myApp.factory('HeaderData', function() { var data = { Visible: true, PageTitle: '' }; return { ... getData = function() { return data; } }; }); 

And assign the model to scope:

myApp.controller('navCtrl', function($scope, HeaderData) { $scope.data = HeaderData.getData(); }); 

And in your HTML:

<div ng-controller="navCtrl"> <div ng-show="data.Visible">HEADER</div> </div> 
Sign up to request clarification or add additional context in comments.

2 Comments

This does the same thing, just different way of passing the data, unless my tests are wrong
No they are not the same thing. Try it out, this is a common 'gotcha' in AngularJS.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.