I have a array defined in controller and passing it to directive using two way binding. In directive, i tried to pushed object into that array but it failed.
.controller("test", function($scope){
$scope.myarr =[];
$scope.$watch("myarr", function(newValue, oldValue){
console.log($scope.myarr); //prints empty arr
},true);
});
.directive('ptest', ['$compile', function($compile) {
var object = {value: 'changed value'};
return {
restrict:"E"
scope: {
myarr:"="
},
template : "<div>{{iobj.value}}<div>",
link: function(scope,elem,attr){
myarr.push(object) ;
}
};
}]);
html
<ptest myarr="myarr"></ptest>
Try scope.myarr.push(object); instead of myarr.push(object)
as #George Lee said try scope.myarr.push(object); and also your directive have a mistake. after restrict:"E" you forgot put ,
return {
restrict:"E", // forgot put ','
scope: {
myarr:"="
},
template : "<div>{{iobj.value}}<div>",
// Code goes here
angular.module('app', [])
.controller("test", function($scope){
$scope.myarr =[];
$scope.$watch("myarr", function(newValue, oldValue){
console.log($scope.myarr); //prints empty arr
},true);
$scope.addItem = function(){
var object = {value: 'changed value2'};
$scope.myarr.push(object);
}
})
.directive('ptest', ['$compile', function($compile) {
var object = {value: 'changed value'};
return {
restrict:"E",
scope: {
myarr:"="
},
template : '<div ng-repeat="item in myarr">{{item.value}}<div>',
link: function(scope,elem,attr){
scope.myarr.push(object) ;
}
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="test">
<ptest myarr="myarr"></ptest>
<input type="button" ng-click="addItem()" value="add">
</div>
Related
I have the following directive:
.directive("feedList", function() {
return {
restrict: 'E',
scope: {
feeds: '=feedData'
},
templateUrl: 'jstemplates/feed-list.html',
link: function(scope) {
angular.forEach(scope.feeds, function(value, key) {
if(value.who.fullname == " "){
scope.feeds[key].fullname = "email";
}
console.log(value.who.fullname);
});
}
}
})
Inside my template there is an event: ng-click="do()". How to handle this event in directive ot in parent controller?
As it's your isolated scope directive, so pass the callback function and then call that function directly from template or from controller or link function.
Working fiddle
var app = angular.module('myApp', []);
app.controller('AppCtrl', function($scope){
$scope.testFunction = function(){
alert("Called from isolated scope directive");
};
});
app.directive("isolatedScopeDirective", function(){
return{
scope:{
go:"&"
},
template : `<button ng-click='go()'>Test Button</button>`
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="AppCtrl">
<isolated-scope-directive go="testFunction()"></isolated-scope-directive>
</div>
Here i want to pass $scope.myData of app.js to the directive mcsaForm and use the object attributes in myTemplate.html. My code is working properly except the approach which i mentioned above.
app.js
myApp.controller("myCont", function($scope){
.
some code
.
.
$scope.getTypeOfEvent = function(typeOfEvent, idOfEvent)
{
if(typeOfEvent == "MCQ")
{
if(idOfEvent)
{
var indexOfEvent =$scope.namesTwo.Events.indexOf("idOfEvent")+1;
var valueAtIndex = $scope.namesTwo.Events[indexOfEvent].id;
$scope.myData = $scope.namesTwo[valueAtIndex];
console.log($scope.myData); // output: Object {eventId: "001", TimeOfEvent: "2", EventType: "MCQ"}
}
//fetchJsonDir.gettingContData;
$scope.mCSSQ(typeOfEvent,idOfEvent);
}
}
});
myDirective.js
videoCourseApp.directive("mcsaForm",['fetchJsonDir', function(fetchJsonDir){
return{
restrict: "C",
templateUrl: "assets/template_blocks/Preview_forms/myTemplate.html",
scope: {
myData: "="
},
compile: function(scope, element, attrs)
{
$("#mcss_option_list").append("Hello");
},
controller: function($scope){
$scope.onSubmitHidePanel = function()
{
$(".mcsa_form").fadeOut("slow", function(){
$(this).remove();
});-
}
}
}
}]);
myTemplate.html
<div id=mcss_option_list>
</div>
<div>
001, 2, MCQ//print myData.eventId, myData.TimeOfEvent or whatever..
</div>
Use your directive like
<div class="mcsa-form" my-data="myData"></div>
You will get the value in your directive's myTemplate.html
<div id=mcss_option_list>
{{myData.TimeOfEvent}}
</div>
I know that if I have a directive in HTML, I can pass objects from my $scope to it:
<mydirective some-data="someData"></mydirective>
...where someData might be JSON object.
Is it possible to pass a reference to someData if I create the directive dynamically and use $compile?
$scope.someData = { firstName: 'John', lastName: 'Doe' };
var link = $compile("<mydirective some-data='???'></mydirective>");
var content = link($scope);
$(body).append(content);
Yes you can pass object to
var myApp = angular.module('myApp',[]);
myApp.directive('passObject', function() {
return {
restrict: 'E',
scope: { obj: '=' },
template: '<div>Hello, {{obj.prop}}!</div>'
};
});
myApp.controller('MyCtrl', function ($scope) {
$scope.obj = { prop: "world" };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script>
<div ng-controller="MyCtrl">
<pass-object obj="obj"></pass-object>
</div>
var myApp = angular.module('myApp',[]);
myApp.directive('passObject', function() {
return {
restrict: 'E',
scope: { obj: '=' },
template: '<div>Hello, {{obj.prop}}!</div>'
};
});
myApp.controller('MyCtrl', function ($scope) {
$scope.obj = { prop: "world" };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js"></script>
<div ng-controller="MyCtrl">
<pass-object obj="obj"></pass-object>
</div>
directive
I have a custom filter set up that triggers when the user clicks on a checkbox. I use a directive to render the DOM elements, and attach a listener on the checkbox which when clicked, triggers the filter function that's exposed on the $scope.
The $scope.model which is used in the view should get overwritten by the result of the filter function, and the return object looks ok (e.g. the console.log()) but the view doesn't update. What am I doing wrong?
http://jsfiddle.net/r3pXc/1/
The view:
<body ng-app="app">
<div ng-controller="mainCtrl">
<div list-directive />
</div>
The template:
<script type="text/ng-template" id="list.html">
<input type="checkbox" class="control">
<div ng-repeat="player in model">
Name: {{player.firstName}}, Price: {{player.price}}
</div>
</script>
The module and controller:
var app = angular.module('app', []);
app.controller('mainCtrl', ['$scope', '$filter', function($scope, $filter){
$scope.model = [{ firstName: 'foo', price: 100 }, { firstName: 'bar', price: 50 }, { firstName: 'foobar', price: 0}];
$scope.filter = function() {
$scope.model = $filter('listFilter')($scope.model);
console.log($scope.model);
}
}]);
The directive:
app.directive('listDirective', function(){
return {
restrict: 'AE',
templateUrl: 'list.html',
link: function($scope, iElm, iAttrs, controller) {
iElm.bind('click', function(e){
var el = angular.element(e.target);
if (el.hasClass('control')) {
$scope.filter();
};
});
}
};
});
And the filter:
app.filter('listFilter', function(){
return function(input) {
var results = [];
angular.forEach(input, function(val, key){
if (val.price != 0) {
results.push(val);
}
});
return results;
}
});
Need to manually call the digest cycle with $apply(), because I don't listen on the elements with ng- event handlers:
$scope.filter = function() {
$scope.model = $filter('listFilter')($scope.model);
$scope.$apply();
}
I have a directive defined like so:
angular.module('directives.myInput', [])
.directive('myInput', function($parse, $http, $sce){
return {
restrict: 'E',
template: '<input type="text" ng-model="searchStr" />',
controller: function($scope){
$scope.keyPressed = function(event){
$scope.showDropdown = true;
.
.
.
}
}
};
});
And then I have a button in html and directive above declared like so:
<div ng-controller="IndexCtrl">
<button ng-click="startNewLog()">Start</button>
<div ng-controller="ItemNewCtrl">
<myInput />
</div>
</div>
I want to change/initialize ng-model="searchStr" model on a button ng-click. How can I do that?
Thanks guys,
Jani
If I understand you right, first of all you need call child controller with $broadcast. Since we don't use isolate scope, we just call directive method from child controller:
[Short answer]
No isolate scope example
Demo 1 Fiddle
For isolate scope, I would map value to directive that listens on value change automatically:
Isolate scope example
Demo 2 Fiddle
[Full answer]
No isolate scope example
HTML
<div ng-controller = "IndexCtrl">
<button ng-click="startNewLog()">Start</button>
<div ng-controller="ItemNewCtrl">
<my-input></my-input>
</div>
</div>
JS
var app = angular.module('myModule', []);
app.controller('IndexCtrl', function ($scope) {
$scope.startNewLog = function(){
$scope.$broadcast('someEvent');
};
});
app.controller('ItemNewCtrl', function ($scope) {
$scope.$on('someEvent', function() {
$scope.callDirective();
});
});
app.$inject = ['$scope'];
app.directive('myInput', function(){
return {
restrict: 'E',
template: '<input type="text" ng-model="searchStr" />',
controller: function($scope){
$scope.searchStr;
$scope.keyPressed = function(event){
$scope.showDropdown = true;
}
},
link: function(scope, elm, attrs) {
scope.callDirective = function() {
scope.searchStr = 'callDirective';
};
}
};
});
Isolate scope example
HTML
<div ng-controller = "IndexCtrl">
<button ng-click="startNewLog()">Start</button>
<div ng-controller="ItemNewCtrl">
<my-input my-model='contInput'></my-input>
</div>
</div>
JS
var app = angular.module('myModule', []);
app.controller('IndexCtrl', function ($scope) {
$scope.startNewLog = function(){
$scope.$broadcast('someEvent');
};
});
app.controller('ItemNewCtrl', function ($scope) {
$scope.contInput = '';
$scope.count = 0;
$scope.$on('someEvent', function() {
$scope.contInput = 'hey mate';
});
});
app.$inject = ['$scope'];
app.directive('myInput', function(){
return {
restrict: 'E',
scope:{searchStr: '=myModel'},
template: '<input type="text" ng-model="searchStr" />',
controller: function($scope){
$scope.searchStr;
$scope.keyPressed = function(event){
$scope.showDropdown = true;
}
}
};
});