AngularJS Directive Binding to ng-click - angularjs

I currently have the following directive:
return {
restrict: 'E',
scope: {
value: '=',
},
controller: ['$scope',
function ($scope) {
$scope.checked = function (...) { ... };
$scope.toggle = function (...) { ... };
},
],
template: '<input type="checkbox" ng-checked="checked(...)" ng-click="click(...)" />',
};
This works using this syntax:
<checker value='shoes' />
<checker value='pants' />
However - I'd also like to bind to the ng-click event for other purposes. How can I convert to a 'A' directive and still bind to ng-checked and ng-click (without the template) and allow me to use the following syntax:
<input type="checkbox" checker ng-click="other()" />

Related

how can I pass a filter to a directive in Angular?

Similar to this question, I have a directive that I want to use in a couple different situations. I'm passing in a value that it will work with, but I'd also like to pass in a filter to apply to it. What's the right syntax for doing this?
app.directive('showMe', function() {
return {
restrict: 'E',
scope: {
value: '=',
filter: '=',
placeholder: '='
},
templateUrl: 'show-me.html'
};
});
template:
<input ng-model="value" ng-show="editMode" placeholder="{{placeholder}}" />
<p ng-hide="editMode">{{(value | percent)||placeholder}}</p>
use:
<show-me value="item.discount" filter="percent" placeholder="0%" />
expected result:
<input value="25" placeholder="0%" />
or
<p>25%</p>
You could achieve this at a basic level by using the method below; simply use the filter provider within your directive controller, to parse the given value. For example:
<my-directive value="1461782417" filter="date"></my-directive>
Within "myDirective" you could implement the filter very easily like this:
angular
.module('myApp')
.directive('myDirective', {
restrict: 'E',
template: '<span>{{displayValue}}</span>',
scope: {
value: '=',
filter: '='
},
controller: ['$scope', '$filter', function ($scope, $filter) {
// Pass the value
$scope.displayValue = $filter($scope.filter)($scope.value);
}]
});
.filter('percent', function () {
return function (text, length, end) {
if (text == null || text == '') text = '0';
text = parseInt(text) / 100;
return text.toFixed(2);
};

KendoUI directive not working after using Angular $compile

I've defined an Angular directive stField (<st-field>). It dynamically creates a DOM element, <st-field-vov>, and inserts it inside using $compile. I need this dynamic injection because there are other types of fields. The DOM would look like this:
<st-field>
<st-field-vov></st-field-vov>
</st-field>
stFieldVov is another custom directive I create, it handles the rendering of the concrete field. Here is the JS:
(function(module) {
'use strict';
module
.directive('stField', _stField)
.directive('stFieldVov', _stFieldVov);
/*ngInject*/
function _stField($compile, stFieldSvc) {
return {
restrict: 'E',
scope: {
stFieldTmpl: '=',
stDataObjects: '='
},
link: function(scope, $elem) {
var _fieldTmpl = scope.stFieldTmpl,
template = '<st-field-' + stFieldSvc.getFieldTypeShortName(_fieldTmpl.type) + '></div>';
$elem.append($compile(template)(scope));
}
};
}
function _stFieldVov() {
return {
restrict: 'E',
link: function(scope) {
var _fieldTmpl = scope.stFieldTmpl,
_dataObjects = scope.stDataObjects,
_isValue = true;
scope.dataObjectDropDownOptions = {
dataSource: new kendo.data.DataSource({
data: _dataObjects
}),
dataTextField: 'name',
dataValueField: 'id'
};
},
templateUrl: '/widgets/fields/directives/templates/vov.html'
};
}
})(angular.module('st.widgets.fields'));
Here is the template for stFieldVov:
<div class="input-group">
<input type="text" class="form-control" ng-show="isValue()">
<input kendo-drop-down-list
k-options="dataObjectDropDownOptions"
k-option-filter="contains">
<span class="input-group-btn">
<button type="button" class="btn"
ng-class="{'st-btn-do': isDataObject()}">
<span class="icon-server"></span>
</button>
</span>
</div>
The problem is that the k-options for configuring the Kendo widget, kendoDropDownList, doesn't work. I think this is because I used $compile to generate <st-field-vov> as k-options works well if use kendoDropDownList in <st-field>.
The browser doesn't throw any error, it is just that the drop down data is empty.
Thanks for reading.
Try to use this:
$elem.append(template);
$compile($elem.contents())(scope);

AngularJS controller inside directive with binding

I have this simple code of my directive:
app.directive('ngModal', function ($parse) {
return {
restrict: 'E',
template: document.getElementById('ng-modal').innerHTML,
replace: true,
controller : "#",
name:"controllerName",
}
})
<ng-modal controller-name="ModalCtrl"></ng-modal>
And this is my controller:
app.controller('ModalCtrl', ['$scope', function ($scope) {
$scope.model = 'default text'
}])
<div ng-controller="ModalCtrl">
<input type="text" ng-model="model">
</div>
I want, that model field inside my Directive will updated automatically. But I see "default text" always inside directive and changed inside controller. How can I bind it?
You have to add a service to keep information between controllers. Controllers are always created per "view" so your ng-modal and div have different controllers in use, this is why model data is not updated between them.
Fast example:
app.service('sharedData', function() {
var sharedData = {
field: 'default text'
};
return sharedData;
});
app.directive('ngModal', function () {
return {
restrict: 'E',
template: '',
replace: true,
controller : "#",
name:"controllerName",
}
});
app.controller('ModalCtrl', ['$scope', 'sharedData', function ($scope, sharedData) {
$scope.model = sharedData;
}]);
<ng-modal controller-name="ModalCtrl">{{model.field}}</ng-modal>
<div ng-controller="ModalCtrl">
<input type="text" ng-model="model.field">
</div>

Data binding not working in an event in directive

I cannot get the data binding to work in this directive. The variables are not bound properly when I change them inside the event handler,
What am I doing wrong? > Test Fiddle
var myApp = angular.module('myApp', [])
.directive('inputTest', function () {
return {
restrict: 'E',
template: '<div class="input-group">\
<input type="text" class="form-control" />\
<br>child scope: {{myValue}}\
</div>',
scope: {
myValue: '=',
},
link: function (scope, element, attrs) {
$(element).on('click', function (e) {
alert('c');
scope.myValue = 'clicked';
});
scope.myValue = 'not clicked';
},
};
})
function MyCtrl($scope) {
$scope.myValue = 'parent value';
}
HTML
<div ng-controller="MyCtrl">parent scope: {{myValue}}
<input-test my-value="myValue"></input-test>
</div>
Do not forget to call $scope.$apply() at the end of the event handler.
First level bindings may not work as expected due to how prototypical inheritance works. If you try the first point and still get no results, try putting myValue a level deeper:
$scope.data.myValue = 'parent value';
and:
<input-test my-value="data.myValue"></input-test>

Passing ng-model in nested directives

I want to pass my ng-model from the 'outer-directive' to an 'inner-diretive' (which is contained in the outer-directive template).
What is the correct way for doing it?
HTML code:
<body>
<outer-directive ng-model="prop" />
</body>
and directive code:
angular.module('app', []).directive('outerDirective', function(){
return {
template: '<inner-directive ng-model="prop" />',
link: function() { ... }
}
});
You can set up a bi-directional binding (see the documentation, section "Directive Definition Object") with the variable in ngModel attribute, as with any other directives:
<my-directive ng-model="foo"></my-directive>
myApp.directive('myDirective', function () {
return {
template: '<div><input type="text" ng-model="ngModel" /></div>',
replace: true,
scope: {
ngModel : '=',
},
};
});
Fiddle
I think you need to pass the form in the directive and set the form dirty manually.
<directive directive-form="editForm" ></directive>
scope: {
directiveForm:"="
},
link: function (scope, $elem, $attrs){
scope.directiveForm.$setDirty();
}

Resources