I am new to angularjs. I am working with isolated scope. The two way binding using isolated scope is not working. Please check my code. If i remove age : '=' then my code is working fine.
**HTML**
<div ng-controller="homeCtrl">
<my-dir name="{{namee}}" age="{{age}}"></my-dir>
</div>
**JS**
var app = angular.module("home")
app.controller("homeCtrl",["$scope",function($scope){
$scope.namee = "John";
$scope.age= 30;
}]);
app.directive("myDir",function(){
return{
restrict :'E',
scope: {
name : '#',
age : '=',
},
template: ['Directive name is: {{name}}',
'<p>{{age}}</p>'
]
}
})
**Output**
John 30
Directive name is: {{name}} {{age}}
It should be:
<div ng-controller="homeCtrl">
<my-dir name="name" age="age"></my-dir>
</div>
remove the {{}} use just age="age"
Related
I am placing my custom-directive on the fly in my HTML using ng-repat directive.
But the custom-directives are not evaluated and if the placed the same directive on HTML directly then it is working.
...
<body ng-app="docsSimpleDirective">
<div ng-controller="Controller">
<div>This is a Problem</div>
<!--Here in for loop i want to us the value to call a directive-->
<div ng-repeat="var in arr">
<!--Here i am using directive with restrict: 'C' and this is not expending-->
<span class="{{var}}"></span>
</div>
<!-- here my directive named "direct" is working fine -->
<span class="direct"></span>
</div>
</body>
...
and My Js code is
(function(angular) {
'use strict';
angular.module('docsSimpleDirective', [])
.controller('Controller', ['$scope', function($scope) {
$scope.arr = ['direct','indirect'];
}]).directive('direct', function() {
return {
template: 'direct',
restrict: 'C'
};
}).directive('indirect', function() {
return {
template: 'indirect',
restrict: 'C'
};
});
})(window.angular);
I believe there is some compilation issue and i searched web and found $compile can solve my purpose but unable to implement.
Please help me in solving my issue.
Plunker implemention for same : https://plnkr.co/edit/lYGg0UkQpNhN5NJx13Zj?p=preview
Using a directive as a class is bad practice (because unreadable)
https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#restrict-to-elements-and-attributes
Then you pass a directive as a class but dynamically by interpolation which in itself is bad practice (https://docs.angularjs.org/guide/interpolation#known-issues). The class name is interpolated and the element rendered but the directive is not compiled during interpolation.
Remove the restrict lines from your directive definitions and use them as attributes:
<span indirect></span>
Then to use them in the ng-repeat loop, you can check if var = "direct" or "indirect"
https://plnkr.co/edit/JUNFMCZASMntCnC6FsIO?p=preview
Use the directive like this
<div ng-repeat="var in arr">
<span direct ng-if="var == 'direct'"><span>
<span indirect ng-if="var == 'indirect'"><span>
<div>
and in controller define restrict as attribute.
.directive('direct', function() {
return {
template: 'direct',
restrict: 'A'
};
After searching and trying lots of things, I can't seem to find a solution to pass a scope object into a include file.
I have tried
<span ng-init="list_title = clients_list.title;
list_subtitle = clients_list.subtitle;
list_array = clients_list.clients"
ng-include="'/views/partials/lists/list_with_qty.html'">
</span>
and
<span onload="list_title = publishers_list.title;
list_subtitle = publishers_list.subtitle;
list_array = publishers_list.clients"
ng-include="'/views/partials/lists/list_with_qty.html'">
</span>
and
<span ng-include-variables="list_title = publishers_list.title;
list_subtitle = publishers_list.subtitle;
list_array = publishers_list.clients"
ng-include="'/views/partials/lists/list_with_qty.html'">
</span>
they both pass through the object when called on the page by themselves.
However I am trying to include both of these includes one after another.
How can I pass through the variables so that the result isn't the same.
Thanks in advance.
Please refer this plunkr http://plnkr.co/edit/M9cIxNfRIWA8gB41rx1Q?p=preview I have made directive with isolated scope. Replace your template with given list.html
angular.module('app', []).directive('listWithQty', function() {
return{
scope: {
listTitle: '=',
listSubtitle: '=',
listArray: '='
},
templateUrl: 'list.html'
}
Here i want to update controller scope value as per change in directive scope but its only working outside the ng-repeat and its not working inside ng-repeat..
HTML
<div ng-app="app">
<div ng-controller="MainCtrl">
<div>
<h3>
outside repeat
</h3>
<br> Name <strong>{{name}}</strong>
<div class="directive" my-directive name="name"></div>
<button ng-click="run()">See changes</button>
<br>
<br>
<h3>
Inside repeat
</h3>
<br>
<div ng-repeat="(k,v) in rawdata">
{{k}} {{v.key}} Name <strong>{{name}}</strong>
<div class="directive" my-directive name="name"></div>
<button ng-click="run()">See changes</button>
<br>
</div>
</div>
</div>
JS
var app = angular.module("app", []);
app.controller("MainCtrl", function($scope) {
$scope.name = "HappyNewYear2016";
$scope.run = function() {
alert($scope.name);
}
$scope.rawdata = [{
key: "event1",
}, {
key: "event2",
}];
});
app.directive("myDirective", function() {
return {
restrict: "EA",
scope: {
name: "="
},
template: [
"<div>",
"Name : <strong>{{name}}</strong>; Change name:<input type='text' ng-model='name' /><br/>",
].join("")
};
});
JSFiddle Link
Please help me in updating controller value from directive inside this ngrepeat..
Basically the problem is the $scope.name inside the controller is not the same as you are passing to directive inside the ng-repeat element, because ng-repeat does create a child scope which is prototypically inherited from the parent scope while looping through rawdata object.
There are several ways to solve this problem.
If you wanted to solved this child and parent scope related issue just by using $parent annotation before name which will refers to parent scope.
Plunkr With $parent in directive
Cons:-
But after certain point $parent will make you crazy. Like suppose if you have two or three hierarchy of child scope it will become like $parent.$parent.$parent.name which looks very wiered.
In your case name is of primitive datatype, so while creating child scope the primitive datatypes values of parent scope aren't accessible inside the child scope. That is the reason why you were using $parent to indicates that name belongs to parent scope. You could overcome this problem just by following do annotation while declaring object. Which will help you to make parent scope property available inside the child by following prototypal inheritance.
HTML
<div class="directive" my-directive name="model.name"></div>
Code
$scope.model = {
name: 'HappyNewYear2016'
};
Plunkr with Dot Notation
You could solve this problem just by passing name value from the run function on ng-click="run(name)"
Html
<div ng-repeat="(k,v) in rawdata">
{{k}} {{v.key}} Name <strong>{{name}}</strong>
<div class="directive" my-directive name="name"></div>
<button ng-click="run(name)">See changes</button>
<br>
</div>
Code
$scope.run = function(name) {
alert(name);
}
You could use controllerAs syntax while declaring controller with its alias and the pass the controller name property by its alias.
Working Plunkr
It's all because of how prototypical inheritance works as both scopes directive and controller have same name for model. Child directive shadows the controller model.
Instead of storing controller model directly as variable use it with object.
$scope.data = {
name : 'HappyNewYear2016'
}
Then use it asdata.name to setup in ng-repeat. It will reflect it in parent as well.
I want to use same directives multiple times in one controller in AngularJS. I want to create a list widget that can be used multiple times. I can display two widgets at the same time under the same controller. But, I am unable to bind teamA and teamB data to ng-repeat in my directive. In addition to that, the code fails during addTeamMember() because datasource is undefined. I was hoping that datasource will be updated with teamA and teamB respectively.
Here is the HTML code.
<div ng-controller="myCtrl"><div class="container">
<my-directive datasource="model.teamA"></my-directive>
<my-directive datasource="model.teamB"></my-directive>
</div></div>
Controller.js:
angular.module('app',[])
.controller('myCtrl', [ '$scope', function($scope){
$scope.teamA = {};
$scope.teamB = {};
} ] );
Directive.js:
angular.module('app', [] )
.directive('myDirective', function(){
return{
restrict: 'AE',
templateUrl: 'directive_html.html',
scope: {
datasource: "=TeamMembers"
},
transclude: true,
link: function(scope, elem, attrs){
scope.addTeamMember = function(){
scope.datasource.push({});
};
scope.removeTeamMember = function(item){
scope.datasource.splice(item, 1);
};
}
};
}) ;
directive_html.html:
<div><div class="container">
<div class="form-group" ng-repeat="member in TeamMembers">
<textarea ng-model="member.text" rows="2"></textarea>
Remove
<div>
<button type="button" ng-click="addTeamMember()">Add</button>
</div></div>
Could anyone please help me out here? I want to create custom Widgets that can be used multiple places either in same controllers or in different controllers.
Thanks
As #Neozaru pointed out in comments. You are expecting the directive attribute to be called team-members here:
<div ng-controller="myCtrl"><div class="container">
<my-directive team-members="model.teamA"></my-directive>
<my-directive team-members="model.teamB"></my-directive>
</div></div>
You do this when you define the isolated scope as:
scope: {
datasource: "=TeamMembers"
}
The above line is saying, "team-members is what the outside attribute will be named, but internally I'll refer to the referenced object as scope.datasource".
I am fighting with the validation in an angular directive without success.
The form.name.$error object seems to be undefined, when I submit the name property to the directive template. If i use a fixed name-attribute inside the template, the $error object is fine, but of course identical for all elements.
The html is:
<form name="form" novalidate>
<p>
<testvalidation2 name="field1" form="form" field="testfield4" required="true">
</testvalidation2>
</p>
</form>
The directive looks like this:
app.directive('testvalidation2', function(){
return {
restrict: 'E',
scope: {
ngModel: '=',
newfield: '=field',
required: '=required',
form: '='
},
templateUrl: 'template2.html',
link: function(scope, element, attr){
scope.pattern = /\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/;
scope.name = attr.name;
}
} // return
});`
and finally the template:
<div>
<input name="{{name}}" type="text" ng-model="newfield" ng-required="required" ng-pattern="pattern"> {{FIELD}}</input>
<span ng-show="form.name.$error.required">Required</span>
<span ng-show="form.name.$error.pattern"> Invalid </span>
<p>Output {{form.name.$error | json}}</p>
</div>
I have created a plunker for my Angular Validation Problem
and would be happy, if someone would help me to win the fight.
Michael
I don't have a fix for this but I can tell you what the problem is.
Firstly in your html form="form" should have name of the form form="form2".
Secondly Since you are creating a new scope in the directive, the scope created is a isolated scope which does not inherit from parent, which means that the the template input control that you add would not get added to the parent scope form2.
The only way out currently i can think of is to not use isolated scope.