Reputation: 3462
Why $scope.items
in First
and Second
controllers still have value First
why it doesnot change to value From controller
after invoking Load()
function?
HomeController:
namespace MvcApplication6.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
return View();
}
public JsonResult GetData()
{
string data = "From controller";
return Json(data, JsonRequestBehavior.AllowGet);
}
}
}
Index.cshtml
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css" rel="stylesheet" />
<script src="~/Scripts/jquery-1.9.1.min.js"></script>
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/MyScript/Custom.js"></script>
<script src="~/Scripts/angular-animate/angular-animate.min.js"></script>
<script src="~/Scripts/angular-ui/ui-bootstrap.min.js"></script>
<script src="~/Scripts/angular-ui/ui-bootstrap-tpls.min.js"></script>
<div ng-controller="LoadData" id="data">
</div>
<div ng-controller="First">
{{items}}
</div>
<div ng-controller="Second">
{{items}}
</div>
<script>
$(document).ready(function () {
angular.element(document.getElementById('data')).scope().Load();
});
</script>
Custom.js
var app = angular.module('MyApp', ['ngAnimate', 'ui.bootstrap']);
app.controller('First', function ($scope, sharedProperties) {
$scope.items = sharedProperties.getProperty();
console.log("First controller",sharedProperties.getProperty());
});
app.controller('Second', function ($scope, sharedProperties) {
$scope.items = sharedProperties.getProperty();
console.log("Second controller", sharedProperties.getProperty());
});
app.controller('LoadData', function ($scope,$http, sharedProperties) {
$scope.Load = function () {
$http({ method: 'GET', url: '/Home/GetData' }).
success(function (data, status, headers, config) {
sharedProperties.setProperty(data);
console.log('Loaded data',data);
}).
error(function (data, status, headers, config) {
alert('error');
});
}
}
);
app.service('sharedProperties', function () {
var property = 'First';
return {
getProperty: function () {
return property;
},
setProperty: function (value) {
property = value;
}
};
});
Upvotes: 0
Views: 138
Reputation: 123
The problem is that, in both First and Second controllers, the variables $scope.items
are initialized when the controllers are loaded. After that moment, they are not changed any more.
The order of execution here is as follows:
$scope.items
;$scope.items
;$http
is called, but you never update the value of $scope.items
on either controller.As a possible solution, you can implement a simple callback mechanism (the standard observer pattern). For example:
app.service('sharedProperties', function () {
var property = 'First';
var callBacks = [];
return {
getProperty: function () {
return property;
},
setProperty: function (value) {
property = value;
callBacks.forEach(function(callBack) {
callBack(value);
});
},
registerCallback: function(callBack) {
callBacks.push(callBack);
}
};
});
Then you have your controllers register their callbacks:
app.controller('First', function ($scope, sharedProperties) {
sharedProperties.registerCallback(function(data) {
$scope.items = data;
});
});
Alternatively you can use Angular events to communicate across controllers.
Upvotes: 1
Reputation: 2820
The reason is that you are working with strings. It means that when you calling:
$scope.items = sharedProperties.getProperty();
You're getting the copy of your string. To share the data between controllers, you can modify your controllers as following:
html:
...
<div ng-controller="First">
{{items.getProperty()}}
</div>
...
js:
...
app.controller('First', function ($scope, sharedProperties) {
$scope.items = sharedProperties;
});
...
or modify your service:
app.service('sharedProperties', function () {
// having the 'object' property inside
var property = {value:'First'};
return {
getProperty: function () {
return property;
},
setProperty: function (value) {
property.value = value;
}
}});
Both these solutions works because they're copying the reference to the object which contains the value instead of copying the value itself.
Upvotes: 0