1) bindings
Although the output is correct, ie string and the corresponding DOM structure are ok, this does not mean that values attributes are being interpreted in the same way, and bindings were done in the same way as putting direct generated HTML in view.html , dispensing with directive .
Additionally, there is a serious problem: inputs are not registered in FormController
. That is, an input with name "number", when included dynamically, will not be made available as%
This is so serious that there is a request opened a year ago , with about 60 votes in favor, being actively discussed to date, in order to resolve this issue.
A developer implemented a code that makes a dynamically generated input be included in FormController - people are using it as a solution until that AngularJS officially solves the problem.
Including this code that corrects the problem, your code will work, with minor adaptations.
NOTE: Others have implemented similar solutions: see here and here - as comment on GitHub , This feature will be integrated with AngularJS 1.3 - there we will no longer need to "break the branch" with workarounds as well.
Here's the complete solution ( see running on Plunkr ):
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="[email protected]" data-semver="1.2.12" src="http://code.angularjs.org/1.2.12/angular.js"></script><script>varapp=angular.module('app',[]);app.directive('myModule',function(){return{restrict:'E',replace:true,scope:{name:'@',placeholder:'@',model:'=',modelCtrl:'&'},templateUrl:'/partials/input_text.html'};});//Esteéo"workaround" mencionado:
app.config(['$provide', function($provide) {
$provide.decorator('ngModelDirective', function($delegate) {
var ngModel = $delegate[0], controller = ngModel.controller;
ngModel.controller = ['$scope', '$element', '$attrs', '$injector', function(scope, element, attrs, $injector) {
var $interpolate = $injector.get('$interpolate');
attrs.$set('name', $interpolate(attrs.name || '')(scope));
$injector.invoke(controller, this, {
'$scope': scope,
'$element': element,
'$attrs': attrs
});
}];
return $delegate;
});
$provide.decorator('formDirective', function($delegate) {
var form = $delegate[0], controller = form.controller;
form.controller = ['$scope', '$element', '$attrs', '$injector', function(scope, element, attrs, $injector) {
var $interpolate = $injector.get('$interpolate');
attrs.$set('name', $interpolate(attrs.name || attrs.ngForm || '')(scope));
$injector.invoke(controller, this, {
'$scope': scope,
'$element': element,
'$attrs': attrs
});
}];
return $delegate;
});
}]);
</script>
</head>
<body>
<script id="/partials/input_text.html" type="text/ng-template">
<div>
<input type="text" name="{{name}}" placeholder="{{placeholder}}" ng-model="model">
<small ng-show="modelCtrl().$dirty" class="text-danger">Campo obrigatório</small>
</div>
</script>
<form name="form">
<my-module name="number" placeholder="Number" model="request" model-ctrl="form.number"></my-module>
</form>
</body>
</html>
2)
(Response to the question before it was edited - when it did not have the still> held because it contains relevant information.)
form.number
, $dirty
, and $invalid
are properties of NgModel Controller
You can access these properties, within the same $error
where the element containing the form
attribute is, using:
- o
ng-model
of name
- o
form
of element where attribute name
You are trying to access it this way. However you are not using any element ng-model
.
In your output , you have a form
with an attribute div
. However, according to the documentation, the form="form"
of AngularJS directive is only enforced on elements (but not about attributes , classes or comments ).
So, for starters, you'll need a form
element. Alternatively, you can use the directive form
, but it is recommended for nested forms (in this case , you can use the ngForm
attribute.)
// Assim não funciona. A diretiva "form" não é ativada.
<div form="myForm">
</div>
// Assim funciona. A diretiva "form" é ativada.
<form name="myForm">
</form>
// Assim a diretiva "ngForm" é ativada.
<div ng-form="myForm">
</div>
If you have already a form with ng-form
being the same as you tell view.html , then fine.
// No caso abaixo, é preciso que o elemento esteja dentro de um form cujo "name" seja "myForm"!
<my-module name="number" placeholder="Number" form="myForm" model="request"></my-module>