EDIT/UPDATE I have added a plunker for this issue: http://plnkr.co/edit/mlYKJQc7zQR0dsvDswMo
I am loading in data from the previous page into $scope.visit in my page controller. I would like to have a directive that constructs and loads select elements on the page with options from the database. Here is what I have so far:
app.directive('popList', ['$http', function($http) {
'use strict';
var directive = {
restrict: 'EA',
link: link,
scope: {
popList: '='
},
template: function(elem,attrs) {
return '<select '+
'ng-model="'+attrs.model+'" '+
'ng-options="option.name for option in ddlOpts track by option.id" '+
'required '+
'></select>';
}
};
return directive;
function link(scope, elem, attrs, ctrl) {
var data = {
sTableName: attrs.tbl
};
$http.post('ddl.asmx/populateDDL',data).
then(function(response) {
console.log('This is the value I want to set it to '+scope.$parent.visit.data.state_id);
//ddlOpts loads with no problem
scope.ddlOpts = response.data.d;
});
}
}]);
Then the HTML looks like this:
<div style="width: 5%" class="tableLabel">State</div>
<div
style="width: 27%;"
class="tableInput"
model="visit.data.state_id"
tbl="tblStates"
pop-list="states"
>
</div>
Essentially I pass in the name of the table that holds my drop down options. I also pass in the model which will tell the select what value is the default (if it has one.)
I can get the data loaded into the select element as options with no problem. I have checked the ng-model to ensure that I have the correct value to match to the ng-value. I have tried ng-repeat then started all over with ng-options but I cannot for the life of me get the select option to set the default to the ng-model value.
I am starting to think its because the when the select is constructed its in a different scope than the where the controller set the data to $scope.visit. Can someone explain why the two scopes don't recognize one another or just explain why I can't set my default value to the value stored in the ng-model?
Here is the page controller just in case you need for reference:
app.controller('demographicsFormCtrl', function($rootScope, $scope, $cookies, $http, $window, $route) {
if (
typeof $cookies.get('visitTrack') === 'undefined' ||
typeof $cookies.get('visitInfo') === 'undefined' ||
typeof $cookies.get('visitData') === 'undefined'
){
window.location.href = "#/";
return false;
}
$scope.visit = {};
$scope.visit.track = JSON.parse($cookies.get('visitTrack'));
$scope.visit.data = JSON.parse($cookies.get('visitData'));
$scope.visit.info = JSON.parse($cookies.get('visitInfo'));
$rootScope.preloader = true;
console.log('controller set');
});
First, thanks to Ravi as I couldn't have found the answer without him...
OK so here is the skinny on doing this in a directive. The database was sending down an object with just a key and an integer value. Angular, when using ng-options, was creating an object with k/v pairs of id-int, name-string... As you can see here in this plunk when I converted the database data (MANUALLY) to match the outcome of the selected option it worked like a charm...
See it here: http://plnkr.co/edit/mlYKJQc7zQR0dsvDswMo
Essentially when trying to change the value of your directive created just make sure the data object in ng-model matches the data object created by ng-options...
or if you have the same issue with the served data you can write in something after you set ddlOpts to set based on the int sent from the DB like so:
app.directive('popList', ['$http', function($http) {
'use strict';
var directive = {
restrict: 'EA',
scope: {
model: '='
},
template: function(elem,attrs) {
return '<select '+
'ng-model="model" '+
'ng-options="option.name for option in ddlOpts track by option.id" '+
'required '+
'></select>';
},
link: link
};
return directive;
function link(scope, elem, attrs) {
var defaultInt;
if (typeof scope.model === "number"){
defaultInt = scope.model;
}else{
defaultInt = parseInt(scope.model);
}
var data = {
sTableName: attrs.tbl
};
$http.post('/emr4/ws/util.asmx/populateDDL',data).
then(function(response) {
scope.ddlOpts = response.data.d;
// THIS LINE BELOW HERE SETS THE VALUE POST COMPILE
angular.forEach(scope.ddlOpts, function (v, i) {
if (v.id === defaultInt) {
scope.model = v;
}
});
});
}
}]);
iTS ALWAYS BETTER AS A RULE OF THUMB TO HAVE YOUR DATA COMING FROM THE db MATCH WHAT ANGULAR CREATES BUT THAT IS NOT ALWAYS SO...