如何将服务注入指令 Link 函数
How to Inject Services into Directive Link Functions
AngularJS 重复指令实例 - 如何保留 link 函数 DRY 以避免在指令的多个实例上重复?
标题几乎说明了一切,但总而言之,我想将下面的 link 函数移动到一个公共位置,以便在指令的多个实例化中我没有相同的 [=30] 集=] 函数存在于每个指令中,而是在公共位置有一组 link 函数?
如何进行这项工作?
指令
angular.module('Risk').directive('webixUi', WebixElement);
function WebixElement(){
return {
restrict: 'A',
scope: {
elem: '@'
},
controller: function($scope, CommonService){
$scope.getTextValue = function(obj, model, type, field){
CommonService.getTextValue(obj, model, type, field);
}
},
link: function (scope, element, attrs) {
function clearLevel(){
leveldiv = document.querySelector("div[name='level']");
leveldiv.innerHTML = '';
leveldiv.setAttribute('class', '');
}
function assignRiskLevel(obj){
l = scope.$parent.risk.likelihood;
t = scope.$parent.risk.technical;
s = scope.$parent.risk.schedule;
c = scope.$parent.risk.cost;
if (validLevel(obj) && riskNotEmpty(l,t,s,c))
{
if (riskIsValid(l,t,s,c))
{
l = Number(l);
tech = Number(t);
schd = Number(s);
cost = Number(c);
c = Math.max(tech,schd,cost);
displayLevel(scope.$parent.riskMatrix[l][c],l,c);
clearDot();
drawDot(l,c);
}
}
else
{
clearLevel();
clearDot();
}
}
function isLevelField(id){
return (id == 'likelihood' || id == 'technical' || id == 'schedule' || id == 'cost');
}
function clearValidation(id){
(document.querySelector('#'+id+ ' > div.webix_control')).classList.remove("webix_invalid");
}
function makeInvalid(id){
(document.querySelector('#'+id+' > div.webix_control')).classList.add("webix_invalid");
}
function validLevel(obj){
return obj.getValue().charCodeAt(0) - '0'.charCodeAt(0) >= 1
&& obj.getValue().charCodeAt(0) - '0'.charCodeAt(0) <= 5;
}
function riskIsValid(l,t,s,c){
var lvl = [l,t,s,c];
valid = true;
for (var idx = 0; idx < lvl.length; idx++)
if ((lvl[idx].charCodeAt(0) - '0'.charCodeAt(0) < 1) || (lvl[idx].charCodeAt(0) - '0'.charCodeAt(0) > 5))
valid = false;
return valid;
}
function riskNotEmpty(l, t, s, c){
if (l != '' && t != '' && s != '' && c != '')
return true;
return false;
}
function clearDot(){
levelDiv = document.querySelector("div.level");
if (levelDiv)
levelDiv.parentNode.removeChild(levelDiv);
}
function fieldEmpty(elem){
return elem.getValue() == '' || elem.getValue().trim() == '';
}
function formValid(){
for (var idx = 0; idx < scope.$parent.fields.length; idx++){
field = scope.$parent.fields[idx];
if (isLevelField(field) && !validLevel(scope.$parent.risk[field]))
return false;
else if (scope.$parent.risk[field] == '')
return false;
}
return true;
}
function validate(elem, id){
if (isLevelField(id) && (!validLevel(elem) || fieldEmpty(elem))){
makeInvalid(id);
clearDot();
}
else if (typeof elem !== 'undefined' && (elem.getValue() == 0 || fieldEmpty(elem)))
makeInvalid(id);
if (formValid())
enableElement("#submit");
else
disableElement("#submit");
}
function enableElement(id){
(document.querySelector(id)).removeAttribute('disabled');
}
function disableElement(id){
(document.querySelector(id)).setAttribute('disabled', 'disabled');
}
function validCharacter(c){
return (c >= 32 && c <= 126);
}
function clearTextValue(code, obj, field){
if (!validCharacter(code) || obj.getValue().trim() == '')
{
scope.$parent.risk[field] = '';
return;
}
}
function handleKeyPress(obj, code, attr){
getTextValueAndValidate(code, obj, attr);
validate(obj, attr);
}
function updateAndValidate(code, obj, attr){
clearTextValue(code, obj, attr);
validate(obj, attr);
}
function getTextValueAndValidate(code, obj, field){
clearTextValue(code, obj, field);
clearValidation(field);
scope.getTextValue(obj, scope.$parent, 'risk', field);
validate(obj, field);
}
function drawDot(l, c){
document.querySelector("td[name='risk["+l+"]["+c+"]']").innerHTML
= "<div class='level' style='width:15px; height:15px; background-color: black'/>";
}
function displayLevel(level, l, c){
leveldiv = document.querySelector("div[name='level']");
if (level >= scope.$parent.risklevels.riskhigh)
{
leveldiv.innerHTML = 'H ' + l + '-' + c;
leveldiv.setAttribute('class', 'high');
}
else if (level < scope.$parent.risklevels.riskhigh && level >= scope.$parent.risklevels.riskmedium)
{
leveldiv.innerHTML = 'M ' + l + '-' + c;
leveldiv.setAttribute('class', 'med');
}
else if (level < scope.$parent.risklevels.riskmedium)
{
leveldiv.innerHTML = 'L ' + l + '-' + c;
leveldiv.setAttribute('class', 'low');
}
}
function getConfig(attr, type, width, height, maxlength)
{
var view;
if (type == "level")
view = "text";
else
view = type;
var config =
{
view: view,
value: scope.$parent.risk[attr],
on: {
"onTimedKeyPress": function(code){
var obj = this.eventSource || this;
handleKeyPress(obj, code, attr);
if (type == "level")
assignRiskLevel(obj);
},
"onBlur": function(code){
var obj = this.eventSource || this;
updateAndValidate(code, obj, attr);
}
},
responsive: true,
width: width,
height: height
};
if (maxlength)
config.attributes = {maxlength : maxlength};
return config;
};
scope.$parent[attrs.webixUi] = getConfig(attrs.webixUi, attrs.type, attrs.width, attrs.height, attrs.hasOwnProperty('maxlength')? attrs.maxlength: null);
}
}
}
对两个不同的值重复 webix-ui 指令
<div ng-if="$root.initDone">
<div webix-ui="risktitle" width="500" height="30" type="text"
id="risktitle" name="risktitle" />
</div>
<div ng-if="$root.initDone">
<div webix-ui="riskstatement" width="500" height="97" type="textarea"
id="riskstatement" name="riskstatement" />
</div>
服务可以注入指令构造函数:
angular.module('Risk').directive('webixUi', WebixElement);
̶f̶u̶n̶c̶t̶i̶o̶n̶ ̶W̶e̶b̶i̶x̶E̶l̶e̶m̶e̶n̶t̶(̶)̶{̶ ̶
function WebixElement(DOMops){
return {
restrict: 'A',
scope: {
elem: '@'
},
controller: function($scope, CommonService){
$scope.getTextValue = function(obj, model, type, field){
CommonService.getTextValue(obj, model, type, field);
}
},
link: function (scope, element, attrs) {
var clearLevel = DOMops.clearLevel;
/**
function clearLevel(){
leveldiv = document.querySelector("div[name='level']");
leveldiv.innerHTML = '';
leveldiv.setAttribute('class', '');
}
**/
将常用功能移至该服务。
AngularJS 重复指令实例 - 如何保留 link 函数 DRY 以避免在指令的多个实例上重复?
标题几乎说明了一切,但总而言之,我想将下面的 link 函数移动到一个公共位置,以便在指令的多个实例化中我没有相同的 [=30] 集=] 函数存在于每个指令中,而是在公共位置有一组 link 函数?
如何进行这项工作?
指令
angular.module('Risk').directive('webixUi', WebixElement);
function WebixElement(){
return {
restrict: 'A',
scope: {
elem: '@'
},
controller: function($scope, CommonService){
$scope.getTextValue = function(obj, model, type, field){
CommonService.getTextValue(obj, model, type, field);
}
},
link: function (scope, element, attrs) {
function clearLevel(){
leveldiv = document.querySelector("div[name='level']");
leveldiv.innerHTML = '';
leveldiv.setAttribute('class', '');
}
function assignRiskLevel(obj){
l = scope.$parent.risk.likelihood;
t = scope.$parent.risk.technical;
s = scope.$parent.risk.schedule;
c = scope.$parent.risk.cost;
if (validLevel(obj) && riskNotEmpty(l,t,s,c))
{
if (riskIsValid(l,t,s,c))
{
l = Number(l);
tech = Number(t);
schd = Number(s);
cost = Number(c);
c = Math.max(tech,schd,cost);
displayLevel(scope.$parent.riskMatrix[l][c],l,c);
clearDot();
drawDot(l,c);
}
}
else
{
clearLevel();
clearDot();
}
}
function isLevelField(id){
return (id == 'likelihood' || id == 'technical' || id == 'schedule' || id == 'cost');
}
function clearValidation(id){
(document.querySelector('#'+id+ ' > div.webix_control')).classList.remove("webix_invalid");
}
function makeInvalid(id){
(document.querySelector('#'+id+' > div.webix_control')).classList.add("webix_invalid");
}
function validLevel(obj){
return obj.getValue().charCodeAt(0) - '0'.charCodeAt(0) >= 1
&& obj.getValue().charCodeAt(0) - '0'.charCodeAt(0) <= 5;
}
function riskIsValid(l,t,s,c){
var lvl = [l,t,s,c];
valid = true;
for (var idx = 0; idx < lvl.length; idx++)
if ((lvl[idx].charCodeAt(0) - '0'.charCodeAt(0) < 1) || (lvl[idx].charCodeAt(0) - '0'.charCodeAt(0) > 5))
valid = false;
return valid;
}
function riskNotEmpty(l, t, s, c){
if (l != '' && t != '' && s != '' && c != '')
return true;
return false;
}
function clearDot(){
levelDiv = document.querySelector("div.level");
if (levelDiv)
levelDiv.parentNode.removeChild(levelDiv);
}
function fieldEmpty(elem){
return elem.getValue() == '' || elem.getValue().trim() == '';
}
function formValid(){
for (var idx = 0; idx < scope.$parent.fields.length; idx++){
field = scope.$parent.fields[idx];
if (isLevelField(field) && !validLevel(scope.$parent.risk[field]))
return false;
else if (scope.$parent.risk[field] == '')
return false;
}
return true;
}
function validate(elem, id){
if (isLevelField(id) && (!validLevel(elem) || fieldEmpty(elem))){
makeInvalid(id);
clearDot();
}
else if (typeof elem !== 'undefined' && (elem.getValue() == 0 || fieldEmpty(elem)))
makeInvalid(id);
if (formValid())
enableElement("#submit");
else
disableElement("#submit");
}
function enableElement(id){
(document.querySelector(id)).removeAttribute('disabled');
}
function disableElement(id){
(document.querySelector(id)).setAttribute('disabled', 'disabled');
}
function validCharacter(c){
return (c >= 32 && c <= 126);
}
function clearTextValue(code, obj, field){
if (!validCharacter(code) || obj.getValue().trim() == '')
{
scope.$parent.risk[field] = '';
return;
}
}
function handleKeyPress(obj, code, attr){
getTextValueAndValidate(code, obj, attr);
validate(obj, attr);
}
function updateAndValidate(code, obj, attr){
clearTextValue(code, obj, attr);
validate(obj, attr);
}
function getTextValueAndValidate(code, obj, field){
clearTextValue(code, obj, field);
clearValidation(field);
scope.getTextValue(obj, scope.$parent, 'risk', field);
validate(obj, field);
}
function drawDot(l, c){
document.querySelector("td[name='risk["+l+"]["+c+"]']").innerHTML
= "<div class='level' style='width:15px; height:15px; background-color: black'/>";
}
function displayLevel(level, l, c){
leveldiv = document.querySelector("div[name='level']");
if (level >= scope.$parent.risklevels.riskhigh)
{
leveldiv.innerHTML = 'H ' + l + '-' + c;
leveldiv.setAttribute('class', 'high');
}
else if (level < scope.$parent.risklevels.riskhigh && level >= scope.$parent.risklevels.riskmedium)
{
leveldiv.innerHTML = 'M ' + l + '-' + c;
leveldiv.setAttribute('class', 'med');
}
else if (level < scope.$parent.risklevels.riskmedium)
{
leveldiv.innerHTML = 'L ' + l + '-' + c;
leveldiv.setAttribute('class', 'low');
}
}
function getConfig(attr, type, width, height, maxlength)
{
var view;
if (type == "level")
view = "text";
else
view = type;
var config =
{
view: view,
value: scope.$parent.risk[attr],
on: {
"onTimedKeyPress": function(code){
var obj = this.eventSource || this;
handleKeyPress(obj, code, attr);
if (type == "level")
assignRiskLevel(obj);
},
"onBlur": function(code){
var obj = this.eventSource || this;
updateAndValidate(code, obj, attr);
}
},
responsive: true,
width: width,
height: height
};
if (maxlength)
config.attributes = {maxlength : maxlength};
return config;
};
scope.$parent[attrs.webixUi] = getConfig(attrs.webixUi, attrs.type, attrs.width, attrs.height, attrs.hasOwnProperty('maxlength')? attrs.maxlength: null);
}
}
}
对两个不同的值重复 webix-ui 指令
<div ng-if="$root.initDone">
<div webix-ui="risktitle" width="500" height="30" type="text"
id="risktitle" name="risktitle" />
</div>
<div ng-if="$root.initDone">
<div webix-ui="riskstatement" width="500" height="97" type="textarea"
id="riskstatement" name="riskstatement" />
</div>
服务可以注入指令构造函数:
angular.module('Risk').directive('webixUi', WebixElement);
̶f̶u̶n̶c̶t̶i̶o̶n̶ ̶W̶e̶b̶i̶x̶E̶l̶e̶m̶e̶n̶t̶(̶)̶{̶ ̶
function WebixElement(DOMops){
return {
restrict: 'A',
scope: {
elem: '@'
},
controller: function($scope, CommonService){
$scope.getTextValue = function(obj, model, type, field){
CommonService.getTextValue(obj, model, type, field);
}
},
link: function (scope, element, attrs) {
var clearLevel = DOMops.clearLevel;
/**
function clearLevel(){
leveldiv = document.querySelector("div[name='level']");
leveldiv.innerHTML = '';
leveldiv.setAttribute('class', '');
}
**/
将常用功能移至该服务。