Reputation: 117
So this is a bit complex, and I will try to explain it thoroughly. Ultimately the question I am trying to answer is, "How can I print the model, and not the value of the model, in the HTML?" I believe the answer to that will solve my problem, but I'm going to discuss my problem in full so you all can tell me that I'm probably doing it wrong. In which case I have a lot of re-writing to do, so I hope not.
Scenario: Here is the initial HTML page, where-in 'field' is a custom directive.
<field model="model1" placeholder="Model 1" type="input"></field>
<field model="model2" placeholder="Model 2" type="input"></field>
<field model="model3" placeholder="Model 3" type="input"></field>
Here is the custom directive.
app.directive("Field", function(){
return{
restrict: "E",
scope: { model: '=', placeholder:'@', type: '@'},
templateUrl: function(tElement, tAttrs){
return 'views/common/' + tAttrs.type + '.html';
}
};
});
Here is the Template for the directive. The type attribute just feeds in different templates, this way I don't have to do a complicated if then structure. Bear with me, it's might start to get a bit complex.
<field-label model="model">{{placeholder}}</field-label>
<div class="col-sm-2 no-right-pad">
<input type="text" ng-model="model.value" placeholder="{{placeholder}}" class="form-control input-sm"></input>
</div>
<div class="col-sm-2 no-pad">
<field-options field-options-model="model" class="field-options"></field-options>
</div>
As you should be able to tell, this is a form. Each initial directive call creates a form group containing a label, an input, and a directive with which options can be added to the model. For the sake of this exercise, lets say I want to be able to add a comment to each input. I get a little dirty when you go down into the field-options directive, and I change the model name, it's legacy from previous attempts and isn't hurting anything but I still might change that. I don't necessarily need it because the directives are nested and thus, share $scopes. Here's that directive:
app.directive("FieldOptions", function() {
return {
restrict: "E",
scope: { field: '=FieldOptionsModel' },
templateUrl: 'views/common/field-options.html'
};
});
And that template:
<div class="dropdown">
<a ng-href class="dropdown-toggle btn btn-bars" data-toggle="dropdown" tabindex="-1"><i class="fa fa-bars"></i></a>
<ul class="dropdown-menu pull-right">
<li><a data-toggle="modal" href="#{{field}}-comment-modal">Add Comment</a></li>
</ul>
</div>
<div id="{{field}}-comment-modal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3>Submit Comment</h3>
</div>
<div class="modal-body">
<div class="form-group">
<label class="control-label">Add Comment</label>
<textarea ng-model="field.comments[0].comment" class="form-control"></textarea>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-warning" data-dismiss="modal">Cancel</button>
<button class="btn btn-primary" data-dismiss="modal" href="#">Add Comment</button>
</div>
</div>
</div>
</div>
OK, In case you didn't know, my field-options is a button with a dropdown that chooses a popup. Because we have repeating directives, you can tell instantly that there are essentially 3 identical copies of this popup being stored in the DOM structure right now. 1 for Model1, 1 for Model2, and 1 for Model3. We now have an issue with being able to call up the proper popup for each field group. Since it's built with the same ID usually, there are 3 identical ID's and browsers can't handle that so they only open the first. My solution, as you can see here, is to call the model name and inject it into the ID for the comment popup, thus making it unique per each field group. The problem is that id="{{field}}-comment-modal" does not print out id="model1-comment-modal" like I want it to, it instead prints out id="{"value" = "whatever the value might be set to, or blank if we click to add a comment before we fill out the input."}-comment-modal".
I return to my original question, "How can I print the model string, not the data it represents?" or, what am I doing wrong, or how to stop worrying and get a new job.
Note: Please be gentile, my example is dumbed down, actual use is way more complex and repetitive.
Upvotes: 1
Views: 3868
Reputation: 4935
Not sure it will be possible to output the variable name but your issue can be resolve with one of the following solutions :
Hope this will help.
Update : After a bit of digging it may be possible to retrieve the string model1, model2 from the first directive by using the third attributes of the directive link function :
<field model="model1" placeholder="Model 1" type="input"></field>
angular.module('app', []).directive("field", function() {
return {
restrict: "E",
scope: { model: '=', placeholder:'@', type: '@'},
templateUrl: function(tElement, tAttrs){
return 'views/common/' + tAttrs.type + '.html';
},
link: function(scope, elem, attrs) {
console.log(attrs.model);
//Will output model1
}
}
});
By forwarding this string to the inner directive you may be able to generate unique IDs
Upvotes: 1