This is my scenario,
view:
<div data-ng-controller="MyModuleController">
<div ng-repeat="a in range() track by $index" >
<ty-project idx="$index+1" ng-model="projects[$index]" ></ty-project>
</div>
</div>
controller:
$scope.projects= [];
$scope.range = function() {
// return some random number - it does not really matter for the purpose
};
ty-project is just a directive
angular.module('mymodule').directive('tyProject', [
function() {
return {
templateUrl: 'modules/mymodule/directives/typrojectTemplate.html',
restrict: 'E',
scope: {
idx: '='
},
link: function postLink(scope, element, attrs) {
}
};
}
]);
typrojectTemplate is a simple template with 2 inputs,as following:
<div>
<label>Project_{{idx}} name</label>
<input type="text" name="project.name" ng-model="project.name"/>
</div>
<div >
<label >Project_{{idx}} total </label>
<input type="number" name="project.total" ng-model="project.total" />
</div>
this is my controller
angular.module('mymodule').controller('MyModuleController', ['$scope',
function($scope) {
$scope.projects: [] ;
$scope.save = function() {
console.log(projects);
};
$scope.range = function() {
var n= 2;// todo: return random number..
return new Array(n);
};
}
]);
so in case range method return 2
there will be 2 projects object
each project has name and total attributes.
how can I bind the projects to the controller?
Thanks.
hay you have to pass the scope from the controller to the directive. The directive will pass this scope to the template.
you could do this in your directive:
scope:{
project: '=ngModel'//will pass it to the Template.
idx: '=' //
}
i dont know, whether u assigned the controller to the view.
Related
I am getting a value from a function in controller1. I want to set this value to controller2's directive's template. I am confused on how to use scope in this to achieve the same.
Html
<body ng-app = "myApp" ng-controller="parentcontroller as ctrl">
<div class ="boardcanvas" style ="overflow-x:auto;">
<div id = "board">
<list-wrapper ng-repeat="task in ctrl.tasks track by $index" class ="listwrapper" id = "listwrapper"></list-wrapper>
<add-list-controls class = "controls" tasks ="ctrl.tasks" ng-show ="ctrl.listcontrolarea"></add-list-controls>
</div>
</div>
</body>
Controller1 and its Directive:
angular.module('myApp')
.controller('listController', ['$scope','$compile','$http', function($scope, $compile, $http){
'ngInject';
$scope.tasks=[];
$scope.cardarr =[];
vm.addme = function(){
console.log(vm);
console.log($scope.tasks);
$scope.tasks.push({title: $scope.title, cardarr: []});
}
}])
.directive('addListControls', function() {
return {
restrict: 'E', // Element directive'
controller: 'listController as listctrl2',
scope: { tasks: "=",
cardarr: "="},
template: `<textarea ng-model= "listctrl2.title" placeholder ="Add a List" id="input" style = "position:absolute"></textarea>
<button id="controlbutton" class ="btn btn success" style = "position:absolute" ng-click="listctrl2.addme()">Save
</button>`,
};
});
Controller2 and its Directive:
.controller('listWrapperController', ['$scope','$compile','$http', function($scope, $compile, $http){
'ngInject';
$scope.tasks=[];
}])
.directive('listWrapper', function() {
return {
restrict: 'E', // Element directive
scope:{
tasks: '='
},
controller: 'listWrapperController as listctrl',
template: `<div id="titlebox">
<b class ="card1" tasks="listctrl.task" id ="cardtitle">
{{task.title}} // set the value from controller1 here
</b>
</div> `
};
});
You are initalizing the $scope.tasks array on both controllersand this override the original $scope.task reference (ctrl.tasks) that is set by directive definititon.
Try comment or initialize only if undefined
$scope.tasks= $scope.tasks || [];
$scope.cardarr = $scope.cardarr || [];
The listWrapper directive must be changed andd translate the ng-repeat to its template:
HTML
<list-wrapper tasks="ctrl.tasks"></list-wrapper>
listWrapper directive
(...)
.directive('listWrapper', function() {
return {
restrict: 'E', // Element directive
scope:{
tasks: '='
},
controller: 'listWrapperController as listctrl',
template:
`<div id="titlebox" ng-repeat="task in tasks track by $index" class ="listwrapper" id = "listwrapper">
<b class ="card1" id ="cardtitle">
{{task.title}} // set the value from controller1 here
</b>
</div> `
};
});
I have the following directive:
app.directive('onFileSelected', function() {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element[0]._HANDLE = scope.$eval(attrs.onFileSelected);
element.bind('change', function() {
element[0]._HANDLE();
});
}
};
});
And now, the following html:
<input type="file" name="{{container._id}}" on-file-selected="FileChanged" style="display: block !important;"/>
<div ng-repeat="item in container.items">
<input type="file" name="{{container._id}}" on-file-selected="FileChanged" style="display: block !important;"/>
</div>
In my scope, i have defined the following method:
$scope.container = {
_id: 0,
items: [1,2,3,4,5]
};
$scope.FileChanged = function() {
alert(this.files.length);
};
The Problem is now: This directive works only inside the ng-repeat, but not outside. Any ideas? Am I missing something? Outside of ng-repeat scope.$eval(attrs.onFileSelected); returns undefined.
Thank you!
I want to take a response from a web service and apply it to the ng-options inside the angular.forEach loop. All I think I have to access it is the element itself. Here is the code. Normally I would just write:
scope.whatIWantTheOptionsToB = DBResponse;
But inside the forEach loop I can't do that. How would I set the options variable inside the for each loop.
Here is my code so far:
HTML:
<div class="form__row">
<label>Injury Type:</label>
<select
class="form__select"
ws="populateDDL"
param="tblInjuryTypes"
ng-model="injuryType_id"
ng-options="injury.id as injury.name for injury in injuryTypes"
ng-change="injuryUpdate()"
name="injuryTypes"
required
></select>
</div>
<div class="form__row">
<label>Work Status:</label>
<select
class="form__select"
ws="populateDDL"
param="tblWorkStatus"
ng-model="workStatus_id"
ng-options="status.id as status.name for status in workStatus"
name="workStatus"
required
></select>
</div>
Directive:
app.directive(
'providerForm',
['$http', 'populateDDL', 'classHandler', function ($http, populateDDL, classHandler){
var directive = {
link: link,
scope: true,
restrict: 'E',
templateUrl: '/modules/providerForm.html',
};
return directive;
function link(scope, element, attrs, ctrl) {
var selects = element.find('select');
angular.forEach(selects, function(e,i) {
if (e.attributes['ws'].value === 'populateDDL') {
scope.data = {
sKey: sessionStorage.getItem('key'),
sTableName: e.attributes['param'].value,
iInjuryTypeId: scope.injuryType_id,
iBodyPartId: scope.bodyPart_id
};
scope.getSelectOptions = new populateDDL(e.attributes['ws'].value, scope.data).
then(function(response) {
console.log(e)
scope.whatIWantTheOptionsToBeEachTimeThru = response;
});
}
});
}
}]
);
I have a directive, with an attribute :
html :
<my-directive id="test" myattr="50"></my-directive>
js :
myApp.directive('myDirective', function() {
var link = function(scope, element, attrs) {
scope.$watch('myattr', function(value) {
element.attr('myattr', value);
});
scope.change = function() {
// some code
};
};
return {
restrict: 'E',
template: '<input type="text" ng-change="change()" ng-model="myattr"/>',
scope: {myattr: '='},
link: link
};
});
My goal would be to keep myattr and the value of the input equal. With element.attr('myattr', value) I can force myattr to have the correct value, but how am I supposed to update the input when myattr changes?
For example, in this jsfiddle, when clicking on the button, I try to do :
$('#test').attr('myattr', Math.random() * 100);
But I can't find a way to 'catch' the change from within the directive.
I would like some help modifying the jsfiddle so that :
the function change is called after the jquery call.
the value of the input is always equal to myattr
You need to store the value of myattr as a property on a scope not as a value on an attribute.
Your directive is correct you need to also attach a controller.
var myApp = angular.module('myApp', []);
myApp.controller('MainController', function ($scope) {
$scope.calculate = function () {
// your logic here
alert($scope.val);
}
});
myApp.directive('myDirective', function() {
var link = function(scope, element, attrs) {
scope.change = function() {
console.log("change " + scope.myattr);
};
};
return {
restrict: 'E',
template: '<input type="text" ng-change="change()" ng-model="myattr"/>',
scope: {
myattr: '='
},
link: link
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MainController">
My Value: {{val}} <br/>
<button type="button" ng-click="calculate()">ok</button>
<my-directive id="test" myattr="val"></my-directive>
</div>
</div>
I have a directive as follows,
var myApp = angular.module('myApp', []);
myApp.directive("checkTextCombo", [
"$compile", function($compile) {
return {
restrict: "E",
replace: true,
scope: {
source: '#',
},
link: function(scope, element, attrs) {
scope.rows = eval('(' + scope.source + ')');
},
templateUrl: "../templates/check-text-combo/check-text-combo.html",
controller: function($scope){
$scope.$watch('$scope.rows', function() {
console.log($scope.rows);
});
}
};
}
]);
And a template:
<div ng-repeat="row in rows">
<input type="checkbox" ng-checked="row.checked"/> <label value="{{row.label}}">{{row.label}}</label><input type="textbox" value="{{row.value}}" ng-disabled="!row.checked"/>
</div>
index.html consists of
<check-text-combo source="[{'value':'varsh','label':'name','checked': true}, {'value':'bij','label':'name','checked': false}]"></check-text-combo>
My problem is that, I can a create a template with ng-repeat, but after binding, when I change something in the template, it doesn't change elsewhere. How can I get the modified value?
Got it working after adding ng-model
<div ng-repeat="row in rows">
<input type="checkbox" ng-checked="row.checked" ng-model="row.checked"/> <label value="{{row.label}}">{{row.label}}</label><input type="textbox" value="{{row.value}}" ng-model="row.value" ng-disabled="!row.checked"/>
</div>
You should to change your $watch definition:
$scope.$watch('rows', function() {
// ^
// Here
// rows instead of $scope.rows
console.log($scope.rows);
}, true);
// ^
//and here
// third parameter to true - observed variable is an Object