Reputation: 51084
I have the following Angular declarations, and get no complaints about JS syntax errors or anything like that:
App.js
:
(function () {
'use strict';
var hookPointApp = angular.module("hookPointApp", []);
hookPointApp.controller("agentCtrl", function ($scope, $http) {
$scope.model = {};
...
});
})();
suburbsCtrl
:
(function () {
'use strict';
angular.module("hookPointApp").controller('suburbsCtrl', function ($scope, $http) {
$scope.areas.url = "/Area/ProvinceAreas";
$scope.areas.getOptions = function (provinceId) {
var area = "{'provinceId': '" + provinceId + "'}";
$.ajax({
url: $scope.areas.url,
type: "POST",
data: area,
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false,
cache: false,
success: function (response) {
if ((response !== null) && (typeof response !== "undefined")) {
$scope.areas.options = response;
}
},
error: function (xmlHttp, textStatus, errorThrown) {
alert(errorThrown);
}
});
};
// TODO Get a proper provinceId somehow.
$scope.areas.getOptions(1);
...
});
})();
Then I have a repeater with options declared like:
<div ng-controller="suburbsCtrl">
<div class="form-group">
@Html.LabelFor(model => model.AreaId, new { @class = "control-label" })
<select class="form-control" ng-model="areas.areaId" ng-change='areas.getOptions($("#province.val()"))'>
<option> - Select an Area - </option>
<option id="province" ng-repeat="item in areas.options" ng-value="{{item.Id}}">{{item.Label}}</option>
</select>
</div>
</div>
Yet getOptions
isn't called when I change the select option, and breakpoints I put in the Chrome debugger, even on lines not in functions, execution doesn't stop there, e.g. $scope.areas.getOptions(1);
which is for initializing a dropdown, is not in a function, but below the function declaration, so I want to declare the function then call it immediately afterwards. A breakpoint in the module file, on var hookPointApp = angular.module("hookPointApp", []);
doesn't even work, yet some Angular functionality in the app still sometimes works.
The Angular (core and my own) files are, I think, correctly referenced at the bottom of the body
element in Layout.cshtml
:
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
<script src="~/Scripts/angular/angular.js"></script>
<script src="~/Scripts/angular/angular-resource.min.js"></script>
<script src="~/Scripts/App/App.js"></script>
<script src="~/Scripts/App/suburbsCtrl.js"></script>
@RenderSection("ViewScripts", required: false)
</body>
What could I be doing wrong?
Upvotes: 0
Views: 100
Reputation: 210
First, Instead of referencing your module through a variable, could you use the getter
syntax for the module. I would also split module declaration and c controller definition into separate file. This is in line with John Papa's Angular Style Guide endorsed by the Angular
team:
App.js
(function () {
'use strict';
angular.module("hookPointApp", []);
})();
agentCtrl.js
(function () {
'use strict';
angular.module("hookPointApp").controller("agentCtrl", function ($scope, $http) {
$scope.model = {};
});
})();
Secondly, you should probably use $http
service of Angular
or another library for $http
requests e.g Restangular
. The issue you have is because you are probably using jQuery's
ajax method which upon completion has no way of letting the angular digest loop of knowing that there is a response from the server unless you notify it through $scope.apply()
.
Note that in the Promise
resolution we use the then
method of the promise
and not success
which has been deprecated. Read more here about $http
and the deprecation notice.
Here is suburbsCtrl.js
with the $http
service.
(function () {
'use strict';
angular.module("hookPointApp").controller('suburbsCtrl', function ($scope, $http) {
$scope.areas.url = "/Area/ProvinceAreas";
$scope.areas.url = "/Area/ProvinceAreas";
$scope.areas.getOptions = function (provinceId) {
$http.post($scope.areas.url, {
provinceId: provinceId
}).then(function(data){
if (data) {
$scope.areas.options = data;
}
}).catch(function(err){
console.error(err);
});
};
// TODO Get a proper provinceId somehow.
$scope.areas.getOptions(1);
});
})();
PS- The Angular
documentation encourages using Angular's
services and only using jQuery's
methods when not available. I would recommend trying to use Angular
without external jQuery
dependency and use the inbuilt jqLite
in Angular
for those methods that you would use jQuery
for.
Also look at these resources:
https://docs.angularjs.org/guide
"Thinking in AngularJS" if I have a jQuery background?
Upvotes: 2
Reputation: 131
Try it:
(function () {
'use strict';
angular.module("hookPointApp", []).controller('suburbsCtrl', function ($scope, $http) {
$scope.areas.url = "/Area/ProvinceAreas";
$scope.areas.getOptions = function (provinceId) {
$http.post($scope.areas.url, {
provinceId: provinceId
}).success(function(data){
if (data) {
$scope.areas.options = data;
}
});
};
// TODO Get a proper provinceId somehow.
$scope.areas.getOptions(1);
...
});
})();
Upvotes: 0
Reputation: 131
getOptions() is undefined.
define:
(function () {
'use strict';
angular.module("hookPointApp").controller('suburbsCtrl', function ($scope, $http) {
...
// TODO Get a proper provinceId somehow.
$scope.areas.getOptions(1);
...
$scope.getOptions = function() {
// on change select , call this
};
});
})();
Upvotes: 0